在谷歌代码上找到的一些库中,我遇到了这个 util 方法:
public static void gc(){
Object obj = new Object();
WeakReference ref = new WeakReference<Object>(obj);
obj = null;
while(ref.get()!=null)
System.gc();
}
它的文档说它提供了一种可靠的方法来调用 GC,因为调用 System#gc() 只是一个提示,没有任何保证。我给学长看了,他说我应该想想为什么这个方法无效。 我读了一些关于弱引用的文章,但我仍然很困惑。 有人可以告诉我要点吗?
最佳答案
我对您发布的所谓“安全 GC”习语有直接的经验。
它不起作用。
原因很简单:弱引用被清除的事实不是对象已被收集的信号;它仅意味着它已无法通过任何强引用或软引用访问。根据我的经验,这个信号在对象被回收之前到达。
更好的尝试是使用 Phantom 引用,它至少确保对象已进入 finalizable 状态,但再次,它仍然可以占用堆,并且在实践中它仍然 占据着它。另一种解释可能是这个特定对象,显然驻留在 Eden 空间中,确实被回收了,但是执行它的 GC 运行并不详尽,并且在其他代中有更多内存需要回收。
另一方面,我非常可靠地使用了这个琐碎的习语:
for (int i = 0; i < 3; i++) { System.gc(); Thread.sleep(500); }
尝试一下,看看它是否适合您。 sleep
部分是可选的:仅当 System.gc()
使用并发清除时才需要它。
如果您反对这种方法明显的变化无常,请记住任何显式 GC 处理的方法都是变化无常的。这个至少是诚实的——而且恰好在实际系统上工作。自然地,它是不可携带的,并且可能由于多种原因随时停止工作。即便如此,这也是您所能得到的最好的。
关于Java:可靠地调用 GC?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19030795/