【问题标题】:When does GC starts collecting garbage?GC什么时候开始收集垃圾?
【发布时间】:2015-08-20 20:43:15
【问题描述】:

我对垃圾收集器很幼稚。如果在当前方法执行期间堆内存不足,垃圾收集器是否会等到方法退出?或者它可以在里程碑 1(即在当前方法执行的中间)启动并释放关键字占用的空间(即当前方法的局部变量占用的空间)。

public void myMethod() {

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

  .
  .
  .

// Milestone 3 - Exit here 

}

【问题讨论】:

  • 如果垃圾回收会释放内存,您的程序将永远不会抛出OutOfMemoryError。垃圾回收随时可能发生。

标签: java memory-management memory-leaks


【解决方案1】:

简短的回答:垃圾收集器永远不会收集当前正在使用的空间。因此,在您的示例中,只要 keywords 在范围内,它引用的任何内容都不会被收集。但是,当您将它分配给 null 时,它用来引用的对象可能符合收集条件,如果没有其他人引用它们。这并不意味着这些对象被收集,只是它可能发生。

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

也就是说,垃圾收集是 JVM 中的一个常见特性。 Java 语言规范 8 在第 1 章中指出:

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

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

运行垃圾收集器。

调用 gc 方法提示 Java 虚拟机扩展 努力回收未使用的对象以使内存 它们目前占用可用于快​​速重复使用。当控制权返回 从方法调用来看,Java虚拟机已经尽了最大的努力 从所有丢弃的对象中回收空间。

接着说System.gc() 等价于Runtime.getRuntime().gc()。该方法的 JavaDoc 说:

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

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

所以,以下是要点:

  1. 规范不要求垃圾收集
  2. 无论如何它都是 JVM 的常见部分
  3. 您无法真正控制它,您只能“建议”JVM 进行一些垃圾回收
  4. 垃圾收集通常发生在它自己的线程中,只要 JVM 想要它发生,所以它是完全不可预测的

【讨论】:

    【解决方案2】:

    Java 垃圾收集器在后台运行,它基本上可以随时启动。它更有可能在程序请求新内存时运行,但无法确定 GC 何时运行。

    【讨论】:

      【解决方案3】:

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

      当内存不足时可以触发 GC(就像 CMS 一样),但是次要收集和并行收集仅在内存不足或直接触发时才会运行。

      【讨论】:

        猜你喜欢
        • 2015-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-17
        • 2016-02-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多