JVisualVM可以"堆转储"按钮释放内存吗?

elD*_*ioz 6 java memory jvisualvm heap-dump

我有一个非常奇怪的问题.我正在开发一个基于Eclipse Equinox的OSGi应用程序; 它是使用OSGi Log Service(Equinox实现)开发的,现在我正在使用Apache Felix OSGi Log Service实现进行测试.

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

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

13个小时后,平均堆大小达到220 MB,所以我决定分析堆转储,并按下"堆转储"按钮:在此操作之后,JVisualVM图显示使用的堆为20(分钟)-35 (最大)MB(?!?!),这个值是常数.

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

我从未在Equinox OSGi Log Service实现中看到这种行为,所以我怀疑Felix Log涉及这个问题......

谢谢

Fre*_*rik 10

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

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

  • 为什么?因为当您想要查找内存泄漏时,您不希望获得那些没有引用但尚未进行垃圾回收的对象.因此,VisualVM在进行堆转储之前会触发完整的GC. (3认同)
  • @Thomas Hurka我使用它的大部分时间是我想要发现无意的浪费.通常在使用MAT之类的东西来指出GC性能不佳的原因等等. (3认同)
  • 如果您怀疑您的程序在某个内部循环中分配了许多临时对象,您可能希望在收集之前查看堆以查看它们是什么.大多数情况下,您希望让GC完成其工作,但有时它有助于提高性能以避免在CPU密集型代码中分配/ gc. (3认同)

Tom*_*icz 3

为什么你还要被 GC 困扰?如果内存被正常释放,则无需担心。但是,如果您想找出导致堆增长的原因(即使这不是泄漏),请查看以下内容:How can I take a heap dump on Java 5而不先进行垃圾收集?