当旧的jvm超过一定比例时,如何自动转储内存?

时间:2014-04-23 14:51:22

标签: java garbage-collection jvm dump

我经常发现我忙碌的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转储它的内存吗? 或任何其他有用的方法可以帮助?
非常感谢!

2 个答案:

答案 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");