1

垃圾回收识别不再被任何变量引用的对象,然后回收对象占用的内存。

我不知道这个过程是定期完成还是对象引用计数下降到零时完成。

假设,如果当对象引用计数降至零时 GC 立即工作,则无需通过调用 System.GC() 来请求 GC;那么,在这种情况下,此方法的目的是什么?

4

6 回答 6

4

GC 既不会定期进行,也不会在对象引用计数降至零时立即进行(注意:大多数 JVM 实现不使用引用计数算法,因此最后一点没有实际意义)。

GC 何时运行由垃圾收集算法决定。

于 2012-06-13T04:54:26.790 回答
1

这是由垃圾收集算法决定的。即使有像System.gc ()Runtime.gc ()这样的方法用于向JVM发送垃圾收集请求,但不能保证垃圾收集会发生。

于 2012-06-13T05:01:48.970 回答
1

当您调用 时System.gc(),您会告诉垃圾收集器进行清理。问题是尚不清楚何时GC会响应您的请求。更重要的是,GC当您调用它时,它可能根本不运行。在 java 中,您无法预测GC将如何工作。(这就是为什么将清理代码放在Object'finalize()方法中被认为是不好的做法的原因)。在Java中,引用对象外的对象会被自动收集为垃圾。这就是为什么您不需要调用System.gc(). 在特殊情况下,当您想尽可能运行它时,您可以尝试使用此方法,但不能保证行为。(如上所述)。

于 2012-06-13T06:53:55.110 回答
1

大多数现代 JVM 使用“stop-the-world”垃圾收集器,即停止程序中所有应用程序线程的垃圾收集器,执行垃圾收集,然后恢复应用程序线程。这意味着在进行垃圾收集之前,应用程序中的所有线程都应该达到可以安全停止线程的点。

于 2013-04-19T16:09:01.003 回答
0

如果一个对象无法从任何活动线程或任何静态引用中访问,则该对象有资格进行垃圾收集或 GC,换句话说,如果一个对象的所有引用都为空,则您可以说该对象有资格进行垃圾收集。循环依赖不计为引用,因此如果对象 A 具有对象 B 的引用并且对象 B 具有对象 A 的引用并且它们没有任何其他实时引用,则对象 A 和 B 都将有资格进行垃圾收集。通常,在以下情况下,对象符合 Java 中的垃圾回收条件:
1) 该对象的所有引用显式设置为 null,例如 object = null
2) 在块内创建对象,一旦控制退出该块,引用就会超出范围。
3) 父对象设置为空,如果一个对象持有另一个对象的引用,并且当您将容器对象的引用设置为空时,子对象或包含的对象自动成为垃圾回收的条件。
4) 如果一个对象只有通过 WeakHashMap 的实时引用,它将有资格进行垃圾收集。

有 System.gc() 和 Runtime.gc() 等方法用于向 JVM 发送垃圾收集请求,但不能保证垃圾收集会发生。

于 2012-06-13T04:55:10.373 回答
0

有两个答案:

  1. JVM 规范、JLS 或任何其他明确的 Java 文档都没有指定垃圾收集器何时运行。因此,它是特定于实现的。

  2. 在实践中,通常使用几种不同的策略。对于非并发收集器,当尝试分配失败时触发 GC,因为没有足够的未分配空间。对于并发收集器,当可用空间量低于预定阈值时开始收集。(对于 HotSpot 并发 GC,阈值比率是一个可调参数。)

没有现代 Java GC 使用引用计数。

的目的System.gc()是允许应用程序向 JVM提示“现​​在是运行垃圾收集器的好时机”。JVM 可以忽略该提示。作为一般规则,以这种方式触发 GC 在 CPU 使用率方面是低效的。在生产代码中这样做的唯一正当理由是为了避免在高度交互的应用程序中出现 GC 暂停。(当您知道不需要交互性时,您会尝试强制 GC;例如,在游戏中的“关卡”之间。)

于 2012-06-13T06:43:53.567 回答