【问题标题】:Call GC on Java heap dump在 Java 堆转储上调用 GC
【发布时间】:2014-12-09 00:58:01
【问题描述】:

假设您获取 Java 堆转储来分析内存泄漏(在-XX:+HeapDumpOnOutOfMemoryError 之后或来自非受控方)。

如何通过调用一些 GC 进程来减少转储中的对象计数,这些进程在转储过程后无论如何都会被 GC 清理?

【问题讨论】:

    标签: java debugging visualvm


    【解决方案1】:

    如果在 GC 之后仍然没有足够的空间,Java 只会抛出内存不足错误。因此,没有可减少的对象计数,堆中的每个对象仍然可以从某个地方访问,否则它会被 OOM 错误之前的 GC 清理。

    【讨论】:

    • 即使在PermGen GC 保证执行?
    • @gavenkoa 你不能转储 PermGen,所以那里也没有什么可以删除的。
    • 来自 JVM 规范,docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.3,第 6.3 节:OutOfMemoryError:“Java 虚拟机实现已用完虚拟或物理内存,并且自动存储管理器无法回收足够的内存以满足对象创建请求。”这意味着如果您在堆上请求一个新对象,则在堆上运行 GC,如果您的对象应该去那里,则在 permgen 上运行。
    • @GuntramBlohm 感谢 JVM 规范! +1
    【解决方案2】:

    可能的解决方案;

    • 在调查内存泄漏时减小堆大小。这会产生更小的转储。
    • 使用像 YourKit 这样的商业工具,它不需要太多内存来分析堆转储。
    • 使用更多内存。您可以花 400 美元左右购买 32 GB。

    您不能转储 PermGen,并且您的转储​​只有可访问的对象,否则您一开始就不会获得 OOME。

    【讨论】:

      【解决方案3】:

      似乎 Eclipse 内存分析器 Can I run Java garbage collection against a heap dump file? 会这样做:

      By default unreachable objects are removed
      

      @Guntram Blohm。正如您所说,OOME 的原因是内存不足或存储管理器无法回收足够的内存。如果您需要长数组来存储碎片内存,则可能根本不执行 GC!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-08
        • 2011-01-08
        • 1970-01-01
        • 2011-06-07
        • 1970-01-01
        • 1970-01-01
        • 2012-09-25
        • 2011-10-09
        相关资源
        最近更新 更多