使用visualvm的Profiler功能,可以提供两方面的性能跟踪功能:
Profile
一个是CPU,可以跟踪每个方法占用CPU的时长;比如你在发现CPU持续走高的时候可以通过Profile的CPU跟踪来确定是哪些函数耗费了性能;
一个是内存,内存的Profile通常可以检测到现存的对象都有哪些,占用了多少内存,对象存在多久等信息;通过内存Profile可以发现可疑的内存泄漏对象,进行分析;还可以针对某一个具体的对象进行内存跟踪,只要右键Class-name列下一行,有一个“log class library”,点击即可切换到跟踪指定对象的内存使用情况。
分析堆栈
可以在monitor的Tab页下,点击“heap dump”,可以会生成一个当前项目的堆栈,在生成的heapdump的标签页中,点击Find按钮即可(如下图)。如果发现某个对象可疑,通过链接进入进行选择,点到了右侧“Inspect”下面某个类,可以产看这个类的都有哪些实例,每个实例的对象情况更等等。
调试大对象
映入眼帘的左侧菜单的选择,是该对象有多少个实例,
远程访问
需要本机运行jstatd服务,并对外开放端口;
在JAVA_HOME/bin目录中,创建名称为jstatdAllPolicy文件(这个文件名称也可以顺便起,不过要与jstatd启动时指定名称相同),将以下内容拷贝到文件中。并保证文件的权限和用户都正确。
grant codebase"file:${java.home}/../lib/tools.jar"{ permission java.security.AllPermission; };
在JAVA_HOME/bin目录中,执行以下命令:
./jstatd -J-Djava.security.policy=jstatdAllPolicy-p 1099 -J-Djava.rmi.server.hostname=192.168.xxx.xxx
如果是tomcat,需要增加在catalina.sh中增加如下参数:
export CATALINA_OPTS=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9998 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false
如果是jar包,则在java -jar XX.jar的后面跟上参数即可。
在远程机器,Remote节点下右键add Remote Host,录入IP后将会添加一个远程的节点,在该节点上面右键,选择“add jstatd Connection...",参数就是参数"com.sun.management.jmxremote.port"中指定的端口号。点击确定即可。
常见调试场景
1. 如果发现内存是锯齿状的,说明不断地有资源被创建,达到了回收上限触发一次回收;
2. 如果检测到Old区的空间被占满,那很可能是有资源没有被是释放,比如大量创建线程,用后没关闭;