使用jvisualvm监控Java程序(本地和远程)

使用jvisualvm监控Java程序(本地和远程)

0 起因

不感兴趣的可以直接从 1 本地Java程序监控 开始看

0.1 发现问题

使用top命令查看Java程序使用的内存,大于设置的最大的使用内存。(top界面查看的是RES字段的值,设置Java程序运行最大堆内存方式是-Xmx方法)

这是我top的结果,大概是650MB。

top查看进程运行状态

这是我执行Java程序的脚本,可以看到-Xmx500m,已经指定了500MB的最大使用堆内存。

运行Java程序的运行脚本

0.2 问题解决

  1. 查询top命令结果中RES字段的具体含义是进程使用的内存,未被换出的也算
  2. 查询-Xmx的含义,就是Java程序使用的最大堆内存。
  3. 通过以上可以说明,这两个含义并不对应。Java中除了堆内存,还有栈内存。所以比我们设置的500MB多也正常。

由此考虑,如何才能监控Java程序使用内存状况呢?经过一番查找知道了Java自带的jvisualvm,但是找到的教程,按照操作又踩了很多坑。这里自己总结一下完整过程。

1 本地Java程序监控

1.1 本地启动jvisualvm

JDK根目录的bin文件夹下可以找到jvisualvm,直接在终端敲命令jvisualvm就可以运行,然后可以看到运行界面。

jVisualVM界面

然后我随便运行一个不会马上关闭的Java程序,例如:

1
2
3
4
5
6
7
8
9
public class Main {
public static void main(String[] args) throws InterruptedException {
for (int i = 10000; i > 0; i--) {
System.out.println("Hello World!");
Thread.sleep(1000);
}
}
}

然后,我们看jvisualvm界面,在右侧可以看到我们运行的程序,双击就可以在右侧看到我们的程序:

Main程序在VisualVM中的展示

具体监控的内容暂时不做介绍,我们继续讲启动方式。

1.2 IntelliJ IDEA的VusalVM

我使用的是IntelliJ Idea进行后台开发的。在IntelliJ Idea中有一个插件VusualVM Luncher

IntelliJ Idea安装VisualVM插件

安装完成之后重启IDEA,然后在以前运行的地方可以看到:

插件运行按钮

如果你之前实验的jvisualvm窗口还开着,那你可以先把它关闭。然后使用Run With VisualVM运行程序,第一次会出现配置界面:

设置插件

选择JDK根目录下,bin文件夹下的jvisualvm就可以了,完成配置,运行程序就可以看到启动了VisualVM,在Windows下可以直接打开运行的应用,但在Mac上不行,要自己双击才行。

2 远程Java程序监控

服务器开发有很多,打的包也不同。我们是直接打成Jar包,然后使用jar命令直接运行jar包。本文只提供jar包方式运行的方法。其他的例如war,使用Tomcat啊什么的可以根据自己开发的具体环境,去网上查找。但是注意2.3步提到的,我在这一步踩了很久的坑。

2.1 远程服务器配置JXM

在远程服务器上的JDK根目录下的/jre/lib/management文件夹下,将jmxremote.password.template文件复制一份jmxremote.password,然后打开jmxremote.password文件。

将里面的这两行注释去掉,monitorRolecontrolRole就是用户名,QEDR&D分别是密码,最后更改了密码,当然和可以使用同样的格式自己添加用户,对于用户的权限是在jmxremote.access文件中配置的,这两个角色的权限默认已经配置了,如果自己添加的用户,你需要自己在这个文件中添加相应的配置,我们暂时就使用controlRole这个角色,因为他的权限比较多:

1
2
#monitorRole QED
#controlRole R&D

2.2 修改启动jar的参数

在运行jar的时候添加如下的参数,没有换行:

1
-Djava.rmi.server.hostname=10.40.2.90 -Dcom.sun.management.jmxremote.port=18999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=true

hostname就是主机的地址,port就是端口号,请确认这个端口号不要被占用。ssl就是要不要加密,我这里链接的开发环境就不加密了,authenticate就是要不要用户认证,账号密码就是上一步中配置的。

然后重新运行程序。

2.3 设置防火墙

敲黑板,注意这里

运行完程序之后关闭服务器的防火墙,有很多教程都是让把上一步中设置的端口号打开,但是其实,JXM还需要监听两个随机的接口。要不直接关了防火墙,要不就把使用到的端口都打开。

2.4 配置jvisualvm

在左侧远程右击添加远程主机

配置远程主机

填写信息之后,可以看到左侧远程下多了一个远程主机,然后右击,选择添加JXM链接

填写链接信息

然后链接OK。

3 VisualVM的使用方法

然后我通过VisualVM监控远程那个程序,看到堆内存只用了300多MB。

VisualVM的使用方法在网上有相当多的文章,这里推荐一篇我觉得还不错的,我就不再写了:

使用 VisualVM 进行性能分析及调优