jvisualvm工具使用

jvisualvm 是JDK自带的具有图形界面操作功能的JVM性能监控和诊断工具,它不仅能分析和诊断堆转储文件,在线实时监控本地JVM进程,还能监控远程服务器上的JVM进程。

1 分析服务器下载dump文件

1)在我们在安装JDK的bin目录双击jvisaulvm.exe程序,程序启动成功后会进入Java VisualVM界面

2)依次点击 文件-> 装入-> 选择文件名和文件类型,文件类型选择【堆Dump】导入我们从服务器上下载的dump文件

3)然后点击【打开】后 Java VisualVM UI 的右边主界面会新增一个Tab页显示导入的dump文件的概要信息

4)点击下面的【显示线程】链接可以看到线程信息

5)点击【概要】右边的【类】可以看到主要占内存的类名、实例数以及占内存大小

可以看到这个堆中占内存前三位的分别是byte[]StringConcurrentHashMap$Node三个类

注意 :生产环境一般不能使用jmap -dump 命令生成堆转储文件,因为执行这个命令的时候会导致STW(应用主线程停顿),影响应用的正常使用。而一般通过设置两个jvm启动参数:-XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath=<filename> 在堆内存溢出时实现自动生成堆转储文件。然后我们从服务器上下载堆转储文件后通过Java VisualVM或者Eclipse Memory Analyzer内存分析工具导入我们下载的dump文件进行分析诊断。

2 分析内存溢出dump文件

首先需要我们设置JVM启动参数测试堆内存溢出时自动导出堆转储文件

1)在我们的本地启动的Java服务中通过IDEA设置启动类参数

四个JVM启动参数分别如下:

-Xms50m
-Xmx50m
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=D:\heapdump\blogDump.hprof

然后点击下面的【ok】使之生效

2)在JVMTestController类中新增一个能导致内存溢出的接口

@GetMapping("/testOutMemoryError")
    public RespBean<List<UserDTO>> outMemoryErrorTest(){
        List<UserDTO> userDTOList = new ArrayList<>();
        for(int i=0;i<1000000;i++){
            UserDTO userDTO = new UserDTO();
            userDTO.setId(i+1);
            userDTO.setUsername("username"+i);
            userDTO.setNickname("张三"+i);
            userDTO.setPhoneNum(18975623568L);
            userDTO.setEmail("ZhangSan"+i+"@163.com");
            userDTO.setEnabled(1);
            userDTO.setRegTime(new Timestamp(System.currentTimeMillis()));
            userDTO.setUpdateTime(new Timestamp(System.currentTimeMillis()));
            userDTOList.add(userDTO);
        }
        RespBean<List<UserDTO>> respBean = new RespBean<>();
        respBean.setStatus(200);
        respBean.setMsg("success");
        respBean.setData(userDTOList);
        return respBean;
    }

3)重启服务后在ApiPost中新建一个http接口,并在请求头中带上用户登录成功后返回的authToken认证信息

点击【发送按钮】一段时间后会返回内存溢出异常信息,同时在D:\heapdump目录下生成了堆转储文件blogDump.hprof

4)我们同样在 Java VisualVM中导入这个dump文件可以看到它的概要信息和类实例信息

内存溢出堆转储概要信息

​ 内存溢出堆转储类实例信息

从内存溢出堆转储实例信息中我们可以看到UserDTO类产生了47899个实例对象占用了4406708字节的堆内存。

3 本地JVM监控

本地监控很简单,打开VisualVM 就可以从左侧栏目里看到本机的应用,点击对应的应用就可以看到对应的内存、线程、GC信息

如果应用出现线程死锁也能通过【线程】tab页看到

点击右上方的【线程 Dump】可以看到线程死锁的具体原因

5 远程JVM监控

VisualVM不仅能监控本地的应用程序,还可以监控远程服务器上的应用,虽然远程监控一般不会用于生产环境的,但是在测试环境做一些压力测试做一些性能的预调优,这个时候使用VisualVM来远程监控测试服务器的JVM使用情况,这样有助于我们了解到JVM的实时运行状态而进行优化和调整。

1)应用配置jmx支持

需要使用VisualVM监控某个远程服务器的JVM应用,那么首先要对需要配置远程监控应用对MX的支持

配置方式:

  • jar包启动:直接 java -jar <jmx相关参数>;
  • tomcat启动:编辑tomcat的catalina.sh配置文件增加JAVA_OPTS配置

jar 包启动配置案例

 nohup java -Dcom.sun.management.jmxremote 
 -Dcom.sun.management.jmxremote.port=8999 
 -Dcom.sun.management.jmxremote.local.only=true 
 -Dcom.sun.management.jmxremote.authenticate=true 
 -Dcom.sun.management.jmxremote.ssl=false 
 -Dcom.sun.management.jmxremote.rmi.port=8999 
 -Dcom.sun.management.jmxremote.access.file=jmx.access 
 -Dcom.sun.management.jmxremote.password.file=jmx.password 
 -Djava.rmi.server.hostname=159.138.489 
  -jar jstx-server.jar&

需要注意的参数:

  • Dcom.sun.management.jmxremote.port:指定jms通讯端口,这个随意只要不与其他应用冲突即可
  • Djava.rmi.server.hostname:连接IP,填写当前服务器的外网IP
  • Dcom.sun.management.jmxremote.ssl:是否位加密连接
  • Dcom.sun.management.jmxremote.authenticate:是否进行权限连接认证,flase 不需要,ture的话就需要指定用户名,密码配置。
  • management.jmxremote.access.file: 用户名 和对应用户的权限配置
  • Dcom.sun.management.jmxremote.password.file:用户名对应的密码
  • 创建用户名密码
  • 如果Dcom.sun.management.jmxremote.authenticate 配置为true则需要进行此步骤

编辑jmx.access文件添加用户名 并指定权限

执行命令:vim jmx.access

添加内容:admin readwrite

jmx.password文件里指定用户名和对应密码

执行命令:vim jmx.access

添加内容:admin 123456

修改password,access文件访问权限:

 Chmod --R 600 jmx.password
 Chmod --R 600 jmx.access

2)建立内网公网IP映射

如果是云服务器则需要建立局域网与公网IP映射

 vim /etc/hosts

3)开放端口访问限制

  • 防火墙:Dcom.sun.management.jmxremote.port对应端口
  • 云服务器安全组策略开放Dcom.sun.management.jmxremote.port对应的端口

4)VisualVM进行远程连接

添加远程服务器:

建立JMX连接:

连接成功:

远程jmx连接成功之后就可以像监视本地JVM进程一样监视远程服务器上的JVM进程了。

不过生产环境远程服务器上的JMV 进程指标的监控大多使用阿里开源的Arthas 中间件进行线上JVM调优。

相关推荐
h^hh42 分钟前
洛谷 P2142 高精度减法(详解)c++
开发语言·c++·算法
励志的小陈1 小时前
printf 与前置++、后置++、前置--、后置-- 的关系
c语言·开发语言
BUG研究员_1 小时前
MQ消息丢失解决方案
java·开发语言
谢道韫6664 小时前
鸿蒙开发新视角:用ArkTS解锁责任链模式
开发语言·arkts
yuanpan4 小时前
23种设计模式之《备忘录模式(Memento)》在c#中的应用及理解
开发语言·设计模式·c#·备忘录模式
wjs20244 小时前
SQLite Alter 命令详解
开发语言
LUCIAZZZ4 小时前
Java中的设计模式违反了哪些设计原则
java·开发语言·spring boot·后端·spring·设计模式
绛洞花主敏明4 小时前
go语言for循环中嵌套defer的执行顺序
开发语言·算法·golang
powerfulzyh4 小时前
StarRocks-fe工程在Cursor中不能识别为Java项目
java·开发语言
Nicole Potter5 小时前
Lua如何实现面向对象的三大特性?
开发语言·游戏·面试·lua