java - 有没有办法知道哪些对象在堆的 "old"区域

标签 java garbage-collection jvm heap-memory

我的 GC 周期很长。 从检查中我看到堆的永久(旧)区域中有太多对象。 是否有任何实用程序可以知道哪些对象位于堆的哪个区域,或者有关这些对象的任何静态信息。
我正在使用 Sun/Oracle HotSpot JVM (Java 6)。

编辑:关于我的问题的更多细节:
我有一个大堆 (32GB),看起来即使旧堆仅占 30%,手动运行 GC 也会暂停 15 秒。我想知道哪些对象是保留在旧区域的“幸存者”,以便知道要优化哪些对象创建。

最佳答案

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

但不利的一面是,我看不出这样的实用程序会有什么帮助。

长时间的 GC 时间通常是因为您的堆太满。随着堆接近 100% 满,在 GC 中花费的时间量趋于呈指数增长。在最坏的情况下,堆会完全填满,您的应用程序会收到 OutOfMemoryError。有两种可能的解决方案:

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

  • 如果根本原因是内存泄漏,则找到并修复它。

在这两种情况下,使用内存分析器将帮助您分析问题。但是你不需要知道哪些对象在老年代。它既与问题的根本原因无关,也与问题的解决方案无关。


I want to know which objects are the "survivors" that remains in the old area, in order to know which object creation to optimize.

这开始变得更有意义了。听起来您需要找出哪些对象是长期存在的……而不是具体它们位于哪个空间。您可以通过使用 jhat 比较一系列堆快照来做到这一点。 (可能还有更好的办法……)

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

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

最后,不清楚你所说的“优化对象创建”是什么意思。你的意思是降低对象创建率?或者您是否正在考虑其他方法来管理长期(缓存?)对象的保留?

关于java - 有没有办法知道哪些对象在堆的 "old"区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10995937/

相关文章:

java - javac 会生成静态桥接方法吗?

java - 通过方法推送对象时是否会创建对象的副本?

java - 我认为java中只有一种类加载器就足够了

java - -XX :G1ReservePercent and to-space exhausted

java - "HttpServletResponse is committed"是什么意思?

java - Spring boot - 如何使用异常处理程序处理页面未找到异常

java - 使用jquery调用soap wsdl

java - JVM 基于堆栈的内存管理的已知尝试

java - Java 持续垃圾收集

java - 分析gc日志