GC何时开始收集垃圾?

Sag*_*gar 1 java memory-leaks memory-management

我对垃圾收集器很天真.垃圾收集器是否等到方法退出,如果堆在当前方法执行期间内存不足?或者它可以在里程碑1(换句话说,在当前方法执行的中间)和关键字占用的空闲空间(换句话说,当前方法的局部变量占用的空间)中启动.

public void myMethod() {

//Milestone 1
 List<Keyword> keywords = callSomeFunction();
 keywords = null;
 .
 .
 .
 .
 //Milestone 2

  .
  .
  .

// Milestone 3 - Exit here 

}
Run Code Online (Sandbox Code Playgroud)

Eri*_*rom 5

简短的回答:垃圾收集器永远不会收集当前正在使用的空间.因此,在您的示例中,只要keywords在范围内,就不会收集它引用的任何内容.但是当您将其指定为null时,如果没有其他人引用它们,它用于引用的对象可能有资格进行收集.这并不意味着那些对象收集,只是它可能会发生.

答案很长:首先,您必须了解Java虚拟机有多种实现.Java 8虚拟机规范中没有要求JVM甚至进行垃圾收集.

也就是说,垃圾收集是JVM中的常见功能.Java语言规范8在第1章中说明:

Java编程语言......包括自动存储管理,通常使用垃圾收集器,以避免显式释放的安全问题(如C的free或C++的删除).

JavaDoc for Java 8将该System.gc()方法记录如下:

运行垃圾收集器.

调用gc方法表明Java虚拟机花费了大量精力来回收未使用的对象,以使其当前占用的内存可用于快速重用.当控制从方法调用返回时,Java虚拟机已尽最大努力从所有丢弃的对象中回收空间.

然后它继续说System.gc()相当于Runtime.getRuntime().gc().该方法的JavaDoc说:

运行垃圾收集器.调用此方法表明Java虚拟机花费了大量精力来回收未使用的对象,以使其当前占用的内存可用于快速重用.当控制从方法调用返回时,虚拟机已尽最大努力回收所有丢弃的对象.

名称gc代表"垃圾收集器".即使未明确调用gc方法,虚拟机也会根据需要在单独的线程中自动执行此回收过程.

所以,这里有一些要点:

  1. 规范不要求垃圾收集
  2. 无论如何,这是JVM的常见部分
  3. 你没有真正控制它,你只能"建议"JVM做一些垃圾收集
  4. 垃圾收集经常发生在自己的线程中,只要JVM希望它发生,所以它完全不可预测