6

我有一个非常奇怪的问题。我正在开发一个基于 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 日志涉及到这个问题......

谢谢

4

2 回答 2

11

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

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

于 2011-03-23T10:04:34.717 回答
3

你为什么还要被 GC 困扰呢?如果内存被适当释放,则无需担心。但是,如果您想了解导致堆增长的原因(即使它不是泄漏),请查看以下内容:如何在 Java 5 上进行堆转储而不首先进行垃圾收集?.

于 2011-03-23T09:59:33.887 回答