我对垃圾收集器很天真。垃圾收集器是否等到方法退出,如果堆在当前方法执行期间内存不足?或者它可以在里程碑1(换句话说在当前方法执行的中间)和关键字占用的空闲空间(换句话说,当前方法的局部变量占用的空间)中启动。
public void myMethod() {
//Milestone 1
List<Keyword> keywords = callSomeFunction();
keywords = null;
.
.
.
.
//Milestone 2
.
.
.
// Milestone 3 - Exit here
}
答案 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)
Java垃圾收集器在后台运行,它可以在任何时候启动。当程序请求新内存时,它更有可能运行,但是没有确定的方法来知道GC何时运行。
答案 2 :(得分:1)
JVM将保存点添加到代码中,以便在执行GC之前将所有线程都置于安全点。这些保存点可以在任何字节代码指令之间发生,但JVM通常会优化这些保存点以减少开销。
当内存不足时可以触发GC(如CMS那样)但是,只有在内存不足或直接触发时才会运行次要集合和并行集合。