3

There are at least two ways, directly or indirectly, of suggesting that the JVM expend effort collecting garbage:

  • System.gc()
  • taking a heap dump and requesting live objects only

In the latter, I can get hold a heap dump programmatically, for example through

hotspotMBean = ManagementFactory.newPlatformMXBeanProxy(ManagementFactory.getPlatformMBeanServer(), "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class);
hotspotMBean.dumpHeap(filename, live);

What difference, if any, is there between what these two operations will do to collect non-strongly-reachable objects?

I believe I have evidence that the heap dump approach is more aggressive than System.gc() in the presence of some combination of weak references, RMI distributed garbage collection and invisible objects strongly-reachable from the stack. In particular that objects that are only weakly reachable locally and have become Unreferenced with respect to RMI appear to be collected only by the heap dump. I haven't yet been able to distil this into a small test case, but it is reproducible.

(Before I'm warned against relying on particular GC behaviour in prod code, I'm not. I discovered this while investigating a potential memory leak, and noticed that the result varied depending on when I took the heap dump. I'm just curious.)

This is using HotSpot 64-Bit Server VM 1.6.0_22 on Windows 7.

4

1 回答 1

1

System.gc() 可能不那么激进,因为它只是指示 JVM 它应该运行 GC。然后 GC 可以自由决定它应该收集(查找并释放内存)所有死对象,其中一些等。它可以决定之前的大收集发生得太近了,现在不是再次收集所有对象的时候了。

我相信转储堆并仅明确询问活动对象将导致 GC 精确计算每个对象是否应该仍然活动。这部分收集工作正在完成,释放死对象使用的内存也不会花费太多。

唉,我没有强有力的证据证明这种行为,这更像是一个疯狂的猜测而不是一个真正的解释。

于 2010-11-11T17:21:03.950 回答