问:如果JVM发生了内存泄漏,如何定位是哪块区域出现了内存泄漏?
答:
- 确定频繁Full GC现象
a.首先通过“虚拟机进程状况工具:jps(JVM Process Status Tool)”找出正在运行的虚拟机进程,最主要是找出这个进程在本地虚拟机的唯一ID(LVMID,Local Virtual Machine Identifier),因为在后面的排查过程中都是需要这个LVMID来确定要监控的是哪一个虚拟机进程。(假设是ID是20954)
jps命令格式:
jps [ options ] [ hostid ]
使用命令如下:
使用jps:jps -l : 参数-l列出机器上所有jvm进程
b.再利用“虚拟机统计信息监视工具:jstat(JVM statistics Monitoring)”是用于监视虚拟机运行时状态信息的命令,它可以显示出虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。
jstat命令格式:
jstat - gcutil pid time :-gcutil 监控jvm的gc信息,pid 监控的jvm进程id,time每个多少毫秒刷新一次;参数也可以是-gc: -gc会显示每个区的容量和使用量。
如下图(从别人那拿的,我自己本地就不贴了):
jstat执行结果:
查询结果表明:这台服务器的新生代Eden区(E,表示Eden)使用了28.30%(最后)的空间,两个Survivor区(S0、S1,表示Survivor0、Survivor1)分别是0和8.93%,老年代(O,表示Old)使用了87.33%。程序运行以来共发生Minor GC(YGC,表示Young GC)101次,总耗时1.961秒,发生Full GC(FGC,表示Full GC)7次,Full GC总耗时3.022秒,总的耗时(GCT,表示GC Time)为4.983秒。 - 找出导致频繁Full GC的原因
使用“Java内存影像工具:jmap”生成堆转储快照(一般称为headdump或dump文件)。
jmap命令格式:
jmap [ option ] vmid
使用命令如下:
jmap -histo:live 20954
这里再借用写别人图(手动狗头)