今天刚刚才加一个故障review会议,故障非常典型,google下也可以找到相似案例介绍。在排查问题的过程中,使用了大量的工具,发现有问题的地方还不只一个,总结一下。(本篇文章不会重点描述案例本身,重点会介绍个人对java内存泄露问题的排查思路和各种工具的使用)。
java内存泄露典型特征
现象一:堆/Perm区不断增长,没有下降趋势(回收速度赶不上增长速度),最后不断触发FullGC,甚至crash(如下两张图是同一个应用的GC和Perm数据,GC触发原因确认是Perm不足)。一般是现象二的晚期表现。

现象二:每次FullGC后,堆/Perm区在慢慢的增长,最后不断触发FullGC,甚至crash(如下图:示意图)
java内存泄露场景---PermGenspace
原因:说明Perm不足。Perm存放class,method相关对象,以及运行时常量对象。如果一个应用加载了大量的class,那么Perm区存储的信息一般会比较大。另外大量的internString对象也会导致Perm区不断增长。此区域大小由-XX:MaxPermSize参数进行设置。(jdk8相关参数已经改变,这里不讨论)
案例:Groovy动态编译class,xstreamString。intern
本质原因:ClassLoader。defineClass和java。lang。String。intern在大量不适宜的场景被调用。
解决方案:
方案1(直接有效):使用btrace相关工具输出调用ClassLoader。defineClass栈信息,从栈信息来追溯问题。(代码如下图)。但Btrace不能tracejvmnative方法(官方releasebtrace1。3。1中版本声明可以tracenative方法,但尝试无效。如果你清楚如何使用,麻烦告知一下,谢谢)。
***用JProfiler来traceString。intern方法栈
方案2:dumpheap,看看哪些class有异常现象(数量),String被Perm区引用的对象信息等。但这种方式不太直观,可以从String数据看看发现可疑问题,没有方案1直观。(如下图:如果能在日常调试推荐JProfiler**)

方案3:增加-XX:+TraceClassLoading和-XX:+TraceClassUnloading,看看哪些class加载了,哪些class卸载了。如果一些特殊的class一直被加载而没有被卸载说明也是有问题的。(如下图)
方案4:执行jmap-permgen(jstat-gcutil可以查看内存增长速度和区域)命令看看Perm区中的内容,初步确定是否存在问题(如下图)
 1/2 1 2 下一页 尾页 |