我经常发现我忙碌的java网络应用程序full-gc 我用jstat监视进程并得到以下结果:
Timestamp S0 S1 E O P YGC YGCT FGC FGCT GCT LGCC GCC
2265116.2 0.00 58.20 79.23 62.57 62.29 273122 5729.765 727 281.867 6011.632 unknown GCCause No GC
2265117.3 0.00 58.20 86.92 62.57 62.29 273122 5729.765 727 281.867 6011.632 unknown GCCause No GC
2265118.3 0.00 58.20 97.72 62.57 62.29 273122 5729.765 727 281.867 6011.632 unknown GCCause No GC
2265119.3 48.51 0.00 13.06 62.84 62.29 273123 5729.791 727 281.867 6011.658 unknown GCCause No GC
2265120.2 48.51 0.00 51.12 62.84 62.29 273123 5729.791 727 281.867 6011.658 unknown GCCause No GC
2265121.3 0.00 42.79 35.43 65.35 62.29 273124 5729.830 727 281.867 6011.697 unknown GCCause No GC
2265122.2 0.00 39.46 50.81 80.86 62.29 273126 5729.998 728 281.883 6011.881 CMS Initial Mark No GC
2265123.3 4.43 4.82 75.57 97.05 62.29 273129 5730.176 729 281.883 6012.060 unknown GCCause Allocation Failure
2265124.3 4.43 4.82 75.57 97.05 62.29 273129 5730.176 729 281.883 6012.060 unknown GCCause Allocation Failure
2265125.3 0.00 7.89 26.93 45.03 62.27 273130 5730.259 729 283.690 6013.949 unknown GCCause No GC
2265126.3 0.00 7.89 35.96 45.03 62.27 273130 5730.259 729 283.690 6013.949 unknown GCCause No GC
2265127.3 0.00 7.89 44.85 45.03 62.27 273130 5730.259 729 283.690 6013.949 unknown GCCause No GC
2265128.3 0.00 7.89 52.71 45.03 62.27 273130 5730.259 729 283.690 6013.949 unknown GCCause No GC
2265129.3 0.00 7.89 61.61 45.03 62.27 273130 5730.259 729 283.690 6013.949 unknown GCCause No GC
我可以看到每20分钟左右,似乎在内存中创建了一个非常大的对象。它太大了,不适合年轻人,它直接分配给老一代
并且它经常导致整个应用程序击中FGC retio(70%)并触发FGC,大对象立即进行GC编辑。所以我无法确定堆转储是什么
这个问题使我的应用程序定期“震动”
我的最大堆是3g,年轻的是521m。 perm-gen总是稳定的
那么,有人可以告诉我,我怎么知道这个巨大的物体到底是什么?
当old-gen超过某个指定的比率时,我可以配置jvm转储它的内存吗?
或任何其他有用的方法可以帮助?
非常感谢!
答案 0 :(得分:0)
如果FullGC对大对象进行GC编辑,您可以使用类直方图来检查堆。
使用-XX:+PrintClassHistogramBeforeFullGC
和-XX:+PrintClassHistogramAfterFullGC.
这至少会显示堆中分配的所有不同类对象,按脚印和实例数排序。
这是一种轻量级方法,但您至少可以检查“一个大对象”的假设。在那之后,您可以使用分析器,例如JDK7u40及更高版本或jProfiler的任务控制都很有效。
答案 1 :(得分:0)
您可能会发现JVM标志有用:-XX:+HeapDumpBeforeFullGC
。它将导致JVM在主要的stop-the-world GC之前将整个堆转储到文件中。该标志是可管理的。这意味着您可以使用JConsole,Misson Control通过JMX在运行时打开/关闭它,甚至可以使用javax.management
API以编程方式打开/关闭它:
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
HotSpotDiagnosticMXBean bean = ManagementFactory.newPlatformMXBeanProxy(
server,
"com.sun.management:type=HotSpotDiagnostic",
HotSpotDiagnosticMXBean.class);
bean.setVMOption("HeapDumpBeforeFullGC", "true");