一、简介
VisualVM 是一款免费的\集成了多个JDK 命令行工具的可视化工具,它能为您提供强大的分析能力,对 Java 应用程序做性能分析和调优。这些功能包括生成和分析海量数据、跟踪内存泄漏、监控垃圾回收器、执行内存和 CPU 分析,同时它还支持在 MBeans 上进行浏览和操作。
在内存分析上,Java VisualVM的最大好处是可通过安装Visual GC插件来分析GC(Gabage Collection)趋势、内存消耗详细状况。
二、GC分析操作简介
Java VisualVM默认没有安装Visual GC插件,需要手动安装,JDK的安装目录的bin目露下双击jvisualvm.exe,即可打开Java VisualVM,点击菜单栏 工具->插件 安装Visual GC
若报:无法连接Java VisualVM 插件中心, 因为Server returned HTTP response code: 503 for URL: http://www.oracle.com。这是插件中心地址错误问题,请参考:https://blog.csdn.net/xionglangs/article/details/77603343
安装完成后重启Java VisualVM,Visual GC界面自动打开,即可看到JVM中堆内存的分代情况:
被监控的程序运行一段时间后Visual GC显示如下
要看懂上面的图必须理解Java虚拟机的一些基本概念:
堆(Heap) :JVM管理的内存叫堆
分代:根据对象的生命周期长短,把堆分为3个代:Young,Old和Permanent,根据不同代的特点采用不同的收集算法,扬长避短也。
-
Young(年轻代)
年轻代分三个区。一个Eden区,两个Survivor区。大部分对象在Eden区中生成。当Eden区满时,还存活的对象将被复制到Survivor区(两个中的一个),当这个Survivor区满时,此区的存活对象将被复制到另外一个Survivor区,当这个Survivor去也满了的时候,从第一个Survivor区复制过来的并且此时还存活的对象,将被复制“年老区(Tenured)”。需要注意,Survivor的两个区是对称的,没先后关系,所以同一个区中可能同时存在从Eden复制过来对象,和从前一个Survivor复制过来的对象,而复制到年老区的只有从第一个Survivor复制过来的对象。而且,Survivor区总有一个是空的。 -
Tenured(年老代)
年老代存放从年轻代存活的对象。一般来说年老代存放的都是生命期较长的对象。 -
Perm(持久代)
用于存放静态文件,如今Java类、方法等。持久代对垃圾回收没有显著影响,但是有些应用可能动态生成或者调用一些class,例如Hibernate等,在这种时候需要设置一个比较大的持久代空间来存放这些运行过程中新增的类。持久代大小通过-XX:MaxPermSize=进行设置。 -
Metaspace(元空间)
随着JDK8的到来,JVM不再有Perm。但类的元数据信息(metadata)还在,只不过不再是存储在连续的堆空间上,而是移动到叫做“Metaspace”的本地内存(Native memory)中。元空间的本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。
GC的基本概念
gc分为full gc 跟 minor gc以及major gc,当每一块区满的时候都会引发gc。
-
minor gc GC
一般情况下,当新对象生成,并且在Eden申请空间失败时,就触发了minor gc GC,堆Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区。然后整理Survivor的两个区。 -
Full GC
对整个堆进行整理,包括Young、Tenured和Perm。Full GC比Scavenge GC要慢,因此应该尽可能减少Full GC。有如下原因可能导致Full GC:上一次GC之后Heap的各域分配策略动态变化,System.gc()被显示调用,Perm域被写满.Tenured被写满
内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。
内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。其实说白了就是该内存空间使用完毕之后未回收。
二 Java VisualVM的其他功能
0.概述
1.监视界面(cpu,类,堆,线程)
2.线程界面
3.Profile界面(性能剖析)
点击CPU按钮执行cpu分析查看方法
点击内存按钮执行内存分析查看类
4.堆dump生成和分析
Dump文件是进程的内存镜像,一般比较大,可以把程序的执行状态通过调试器保存到dump文件中,主要是用来在系统中出现异常或者崩溃的时候来生成dump文件,然后用调试器进行调试,这样就可以把生产环境中的dump文件拷贝到自己的开发机上,调试就可以找到程序出错的位置。
分析服务器jvm 某进程堆内存信息:
jmap -heap <pid>
分析服务器jvm 堆dump文件:
执行 jmap -dump:file=文件名称.dump <pid> #pid为正在运行的java进程pid,必须填
copy dump文件到windows,使用visualVM 加载 dump文件,分析,那一时刻堆内存的详细使用情况
我们可以在启动java进程时,设置如下参数:
参数 | 说明 |
---|---|
-XX:+HeapDumpOnOutOfMemoryError | 内存溢出时自动导出内存快照 |
-XX:HeapDumpPath=E:/dumps/ | 导出内存快照时保存的路径 |
在进程发生oom时自动生成dump文件,然后分析进程崩溃原因,注意dump文件时那一时刻进程使用内存情况,而oom是发生在申请内存大于实际拥有内存,即oom是内存并不一定100%使用。
visualVM 监控的进程可通过: 监视->点击堆dump 按钮来,生成dump文件,并分析
三、参考资料
1、java自带的控工具VisualVM-https://www.cnblogs.com/happy-rabbit/p/6232581.html
2、系统优化怎么做-JVM优化之VisualVM-http://www.imooc.com/article/73034
3、VisualVM工具下载地址-https://visualvm.github.io
4、jvm 内存溢出问题排查方法-https://www.cnblogs.com/lvgg/p/6840644.html
5、visualvm官方使用手册-https://docs.oracle.com/javase/7/docs/technotes/guides/visualvm/
6、使用 VisualVM 进行性能分析及调优-https://www.ibm.com/developerworks/cn/java/j-lo-visualvm/