GC何时开始收集垃圾?

时间:2015-08-20 20:43:16

标签: java memory-management memory-leaks

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

public void myMethod() {

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

  .
  .
  .

// Milestone 3 - Exit here 

}

3 个答案:

答案 0 :(得分:5)

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

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

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

  

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

JavaDoc for Java 8记录了System.gc()方法,如下所示:

  

运行垃圾收集器。

     

调用gc方法表明Java虚拟机耗费   努力回收未使用的物体以制造记忆   它们目前可用于快速重复使用。当控制返回时   从方法调用中,Java虚拟机已尽最大努力   从所有丢弃的物体中回收空间。

然后继续说System.gc()等同于Runtime.getRuntime().gc()。该方法的JavaDoc说:

  

运行垃圾收集器。调用此方法表明Java   虚拟机花费精力来按顺序回收未使用的对象   使他们目前占用的内存可用于快速重用。   当控制从方法调用返回时,虚拟机具有   尽最大努力回收所有丢弃的物品。

     

名称gc代表“垃圾收集器”。虚拟机   根据需要自动执行此回收过程,单独进行   即使没有显式调用gc方法,也可以使用线程。

所以,这里有一些要点:

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

答案 1 :(得分:2)

Java垃圾收集器在后台运行,它可以在任何时候启动。当程序请求新内存时,它更有可能运行,但是没有确定的方法来知道GC何时运行。

答案 2 :(得分:1)

JVM将保存点添加到代码中,以便在执行GC之前将所有线程都置于安全点。这些保存点可以在任何字节代码指令之间发生,但JVM通常会优化这些保存点以减少开销。

当内存不足时可以触发GC(如CMS那样)但是,只有在内存不足或直接触发时才会运行次要集合和并行集合。