【问题标题】:Can JVisualVM "Heap Dump" button release memory?JVisualVM“堆转储”按钮可以释放内存吗?
【发布时间】:2011-07-21 03:55:29
【问题描述】:

我有一个非常奇怪的问题。 我正在开发一个基于 Eclipse Equinox 的 OSGi 应用程序;它是使用 OSGi 日志服务(Equinox 实现)开发的,现在我正在使用 Apache Felix OSGi 日志服务实现对其进行测试。

在 API/代码方面,一切正常:OSGi 日志服务是标准的,所以我可以毫无问题地从 Equinox 切换到 Felix。

但是,我观察到这种奇怪的行为:我将应用程序作为控制台程序启动,以查看控制台上的日志输出,并将其附加到 JVisualVM 以分析内存使用情况; JVisualVM 图显示了一个 80 MB 的已用堆。

13 小时后,平均堆大小达到 220 MB,所以我决定分析堆转储,并按下“堆转储”按钮:在此操作后,JVisualVM 图表显示已用堆为 20(min )-35(max)MBs (?!?!),并且这个值是恒定的。

“堆转储”操作可以释放近 200 mbs 吗?如果是,为什么?

我从未在 Equinox OSGi 日志服务实现中看到过这种行为,所以我怀疑 Felix 日志与此问题有关...

谢谢

【问题讨论】:

    标签: java memory jvisualvm heap-dump


    【解决方案1】:

    “堆转储”操作可以释放近 200 mbs 吗?如果是,为什么?

    是的,它可以。我还没有研究过代码,但我很确定它调用HotSpotDiagnosticMXBean.dumpHeap 并将第二个参数设置为true(如果您从jconsole 或JVisualVM 的MBeans 扩展中调用它,这是默认设置)。根据我的经验,这样做会在转储堆之前触发显式 gc,这可能是“为什么?”的答案。

    【讨论】:

    • 为什么?因为当你想找到内存泄漏时,你不想得到那些没有引用但还没有被垃圾回收的对象。因此,VisualVM 在进行堆转储之前会触发完整的 GC。
    • @Tomas Hurka 是吗?当然,这就是您拥有该选项的原因(尽管其他替代方案也有很好的用途)。我解释了 OP 的“为什么?”更像是“为什么要释放内存?”答案是“因为 VisualVM 要求它在堆转储之前这样做”。
    • 我明白了。你能告诉我另一种选择的真正好处是什么吗?
    • @Thomas Hurka 我使用它的大多数时候是想找出无意的浪费。通常在使用 MAT 之类的东西来确定 GC 性能不佳等原因时。
    • 如果您怀疑您的程序在某个内部循环中分配了许多临时对象,您可能希望在收集之前查看堆以查看它们是什么。大多数情况下,您希望让 GC 完成其工作,但有时避免在 CPU 密集型代码中分配/gc 有助于提高性能。
    【解决方案2】:

    你为什么还要被 GC 所困扰?如果内存被正确释放,则无需担心。但是,如果您想发现导致堆增长的原因(即使它不是泄漏),请查看:How can I take a heap dump on Java 5 without garbage collecting first?

    【讨论】:

    • 在现实世界中,尤其是在金融和其他低延迟领域,您确实希望最大限度地减少 GC 必须执行的工作并分析堆并找出可能的浪费。 “让 GC 完成它的工作”对于大多数 Java 应用程序来说是一个很好的策略,但当 25 毫秒的句号会花费你一个优秀的开发人员每年的成本时,就不是这样了。
    猜你喜欢
    • 2015-04-21
    • 2015-06-26
    • 2011-10-12
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 2019-10-07
    • 2011-04-26
    • 1970-01-01
    相关资源
    最近更新 更多