[讨论] 生产环境web服务器频繁发生full GC时,你如何排查问题?
hittyt
2011-11-04
最近公司一个应用的集群中的机器,jvm总是频繁的发生Full GC。一直没有找到导致频繁Full GC的根本原因,这里想把问题抛出来,请各位大侠分享或者探讨一下解决问题的好的思路或者工具。
起因:从公司的监控工具可以看出,线上某个应用的服务器的Full GC非常频繁,平均差不多一分钟就要来一次。于是通过jmap dump了jvm的堆内存,用visualvm查看dump出来的文件,并没有发现业务上比较异常的类的过多加载。从中看到的比较可疑的倒是有N多的GeneratedMethodAccessor***(***是数字)类在heap中。 于是想通过这一点点线索找出代码中到底哪里频繁使用了反射?但是具体怎么找又是个麻烦事,排除掉底层Spring框架本身进行的大量反射调用,如何找到真正的哪些业务代码使用了这些反射我也没有想到好的工具或者方法。还希望各位不吝赐教。
还有就是想在这里在深入的探讨一下Full GC发生的时机和原因。 这里我先说几个场景: 这里假设OldGen的并发收集采用的是CMS收集器,并发收集启动的Threshold设置为默认的68%,禁用CMS自己动态计算收集时机的功能,只在达到Threshold设定值时才启动CMS(即:在jvm的启动参数中加入了-XX:+UseCMSInitiatingOccupancyOnly) 1、在CMS进行并发收集时,新创建的对象的大小大于Eden+一个survivor区域的大小(所以需要直接晋级OldGen)并且也大于OldGen预留的32%的空间,造成CMS收集的失败,于是触发一次Full GC。 2、CMS还没有进行并发收集,但是新创建的对象的大小大于Eden+一个survivor区域的大小并且也大于目前OldGen剩余空间的总大小,于是触发Full GC。 3、YoungGen在进行Minor GC时,发现现在YoungGen中存活的并且已经old enough的对象的大小的总和已经大于OldGen剩余空间的总大小,于是触发Full GC。 还有哪些情况呢?希望大家一起想一想。
还有个问题,也希望在这里请教一下。就是Full GC和PermGen的关系?在我的知识体系中(如果有错误的地方,还希望大家指正),PermGen占用的空间是在jvm初始分配的堆空间之外的。比如我在jvm的启动参数中设置如下:
-server -Xmx2g -Xms2g -Xmn256m -XX:PermSize=128m 这个表明:希望jvm分配2G作为堆(其中,划分YoungGen256M,其余空间留给OldGen),在这个2G之外,再划分128M的空间给PermGen,用于存放类、方法等元数据信息。这个区域也就是通常所说的方法区。 那么,堆空间中的Full GC是否和PermGen的空间大小有直接或者间接的联系呢?PermGen本身的清理时机又是何时呢? 坐等大家的思维碰撞 :) |
|
caoxudong818
2011-11-04
引用 PermGen占用的空间是在jvm初始分配的堆空间之外的 这个貌似不正确。hotspot的堆包括YongGen、OldGen、PermGen。-XX:PermSize=128m是指定了永生代的大小。虚拟机的直接内存是在2G外另分配的。 永生代满了也会执行垃圾回收的。 |
|
RednaxelaFX
2011-11-04
caoxudong818 写道 引用 PermGen占用的空间是在jvm初始分配的堆空间之外的
这个貌似不正确。hotspot的堆包括YongGen、OldGen、PermGen。-XX:PermSize=128m是指定了永生代的大小。虚拟机的直接内存是在2G外另分配的。 永生代满了也会执行垃圾回收的。 -XX:PermSize/-XX:MaxPermSize不在-Xms/-Xmx的范围内 |
|
caoxudong818
2011-11-04
RednaxelaFX 写道 caoxudong818 写道 引用 PermGen占用的空间是在jvm初始分配的堆空间之外的
这个貌似不正确。hotspot的堆包括YongGen、OldGen、PermGen。-XX:PermSize=128m是指定了永生代的大小。虚拟机的直接内存是在2G外另分配的。 永生代满了也会执行垃圾回收的。 -XX:PermSize/-XX:MaxPermSize不在-Xms/-Xmx的范围内 又错了。 感谢R大指出。 PS. 为啥Javaeye不让发“shi t”一词? |
|
richard_2010
2011-11-07
并发收集启动的Threshold设置为默认的68%貌似小了点吧
ps:64bit的jvm? |
|
neptune
2011-11-09
Eclipse Memory Analyzer
jprofiler IBM® HeapAnalyzer 用这些工具分析head dump文件,看看分析的结果。 |
|
blueswind8306
2011-11-14
用gcLogViewer分析gc.log,记录下FullGC的几个点,再到gc.log中具体去看那段时间的gc情况,一般就可以分析出FullGC的原因。
另外,如果FullGC很频繁的话,也可以直接在服务器上通过jstat观察,对于你说的反射调用特别多这种情况,建议注意看看PermGen的增长是不是FullGC的原因,如果是的话,开大PermGen,或者使用CMS方式对PermGen进行回收。 ps:对于某段代码的调用方是否可以用bTrace跟踪?没用过,提个思路,呵呵。 |