有没有办法知道哪些对象在Heap的"旧"区域

osh*_*hai 11 java heap garbage-collection jvm

我有很长的GC周期.从检查中我看到堆中的旧()旧区域有太多物体.有没有什么可以知道哪些对象在堆的哪个区域,或者关于这些对象的任何静态元素.
我正在使用Sun/Oracle HotSpot JVM(Java 6).

编辑:关于我的问题的更多细节:
我有一个大堆(32GB),看起来即使堆旧区域只有30%满,运行GC手动暂停15秒.我想知道哪些对象是旧区域中的"幸存者",以便了解要优化的对象创建.

Ste*_*n C 7

我不知道任何适用于当前一代JVM的工具/实用程序.

但另一方面,我不知道这样的实用程序会有多大帮助.

通常会发生长GC时间,因为堆太满了.当堆接近100%满时,GC中花费的时间往往呈指数级增长.在最坏的情况下,堆完全填满,你的应用程序得到一个OutOfMemoryError.有两种可能的解决方案:

  • 如果根本原因是堆太小(对于应用程序试图解决的问题的大小),则要么增加堆大小,要么寻找减少应用程序工作集的方法; 即在计算过程中需要"活动"的对象的数量/大小.

  • 如果根本原因是内存泄漏,那么找到并修复它.

在这两种情况下,使用内存分析器都可以帮助您分析问题.但是你不需要知道老一代中有哪些对象.它与问题的根本原因或问题的解决方案无关.


我想知道哪些对象是旧区域中的"幸存者",以便了解要优化的对象创建.

这开始变得更有意义了.听起来你需要找出哪些对象是长寿的......而不是具体到哪个空间.你可以通过jhat比较一系列堆快照来做到这一点.(可能有更好的方法......)

但是,我仍然不认为这种方法会有所帮助.问题是完整的GC需要遍历所有可到达的(硬,软,弱,幻像)对象.如果你有一个30%满32Gb的堆,你仍然有很多对象来标记/扫描/重定位.我认为解决方案可能是使用并发收集器并对其进行调整,以便它能够跟上应用程序的对象分配率.

听起来您可能System.gc()直接从您的代码中调用. 不要那样做! 调用System.gc()将(通常)使JVM执行完整的垃圾回收.这几乎可以保证让你停下来.让JVM决定何时运行收集器要好得多.

最后,目前还不清楚"优化对象创建"的含义.你的意思是降低对象的创建率吗?或者您是否正在考虑管理长期(缓存?)对象的保留?