我有很长的GC周期。 从检查中我看到堆中的旧()旧区域有太多物体。 有没有什么可以知道哪些对象在堆的哪个区域,或者关于这些对象的任何静态 我正在使用Sun / Oracle HotSpot JVM(Java 6)。
编辑:关于我的问题的更多细节:
我有一个大堆(32GB),看起来即使堆旧区域仅满30%,手动运行GC也会暂停15秒。我想知道哪些对象是旧区域中的“幸存者”,以便了解要优化的对象创建。
答案 0 :(得分:7)
我不知道任何适用于当前一代JVM的工具/实用程序。
但另一方面,我不知道这样的实用程序会有多大帮助。
通常会发生长GC时间,因为堆太满了。当堆接近100%满时,GC中花费的时间往往呈指数级增长。在最坏的情况下,堆完全填满,您的应用程序获得OutOfMemoryError
。有两种可能的解决方案:
如果根本原因是堆太小(对于应用程序试图解决的问题的大小),那么要么增加堆大小,要么寻找减少应用程序工作集的方法;即在计算过程中需要“生活”的对象的数量/大小。
如果根本原因是内存泄漏,请找到并修复它。
在这两种情况下,使用内存分析器都可以帮助您分析问题。但是你不需要知道老一代中有哪些对象。它与问题的根本原因或问题的解决方案无关。
我想知道哪些对象是旧区域中的“幸存者”,以便了解要优化的对象创建。
这开始变得更有意义了。听起来你需要找出哪些对象是长寿的......而不是具体到哪个空间。你可以通过使用jhat
来比较一堆堆快照来做到这一点。 (可能有更好的方法......)
但是,我仍然不认为这种方法会有所帮助。问题是完整的GC需要遍历所有可到达的(硬,软,弱,幻像)对象。如果你有一个30%满32Gb的堆,你仍然有很多对象来标记/扫描/重定位。我认为解决方案可能是使用并发收集器并对其进行调整,以便它能够跟上应用程序的对象分配率。
听起来您可能直接从代码中调用System.gc()
。 不要这样做!调用System.gc()
(通常)会导致JVM执行完整垃圾回收。这几乎是保证给你暂停。让JVM决定何时运行收集器会好得多。
最后,目前还不清楚“优化对象创建”的含义。你的意思是降低对象的创建率吗?或者您是否正在考虑管理长期(缓存?)对象的保留?
答案 1 :(得分:1)
工具大象轨迹可以描绘对象的创建和死亡,elephantTrack。通过这种方式,您可以找出比预期更长的存活时间,并且通过方法历史记录,可以获得精确的对象。
但是大堆意味着非常长的配置文件时间和非常大的配置文件。
答案 2 :(得分:0)
我从未见过允许“探索”给定代中对象的工具。
我已经习惯了Netbeans Profiler。它无法真正满足您的要求,但它有一个工具可以让您了解出了什么问题。
使用Profiler运行应用程序,选择Memory
,然后在Live Results
中有一列Generations
。 它没有告诉您每个对象的生成,但它会为您提供Surviving Generations
的数量。因此,如果数字大于1,则可能在终身(可能在幸存者空间中),如果数字总是增长,则会出现内存泄漏。
答案 3 :(得分:0)
我认为没有任何实用工具可以告诉你不同代的对象的数量。
jconsole
。在jconsole的帮助下,您可以连接到您的应用程序并监控所有代,在这里您可能会得到一些我不确定的数字。jmap
进行转储,然后使用eclipse MAT
工具对其进行分析。JVM
参数运行您的应用程序,并在日志中提供有关GC的信息 GC logging is enabled using JVM arguments; below are the arguments I use. (Note: the log file specified as file is reset each time the VM starts.
-verbose:gc -Xloggc:file
我认为这对你有帮助。