在方法调用中,如果我在该调用期间创建一个对象。那么这些对象何时被垃圾回收?它们是否被放置在堆上,并与堆上的其他对象一起被垃圾回收?还是因为它们不再需要而更早地被垃圾回收了?该方法的执行已经完成。
方法范围内创建的对象在方法关闭时就可以进行垃圾回收 - 除非该引用作为返回值传递回去。在这种情况下,调用者可能会保留该引用并防止其被垃圾回收。
由于垃圾收集器根据自己的规则运行在自己的线程上,因此您不能确切知道何时清除对象,或者其他地方分配的对象是否也符合条件。
方法的执行已经结束,对象现在超出范围这个事实是无关紧要的。
垃圾回收是运行时系统的隐式操作,它在与您的代码并行的单独线程中实现一个特定的垃圾回收算法。
垃圾回收线程在不可预测的时间运行,根据Java文档,通常每秒钟左右,在内存几乎耗尽的情况下,评估哪些对象有资格进行垃圾回收,即从根指针(例如静态变量)没有对它们的引用。
因此,通过根指针可访问的每个对象都会被标记,然后递归地引用这些对象等等。
这可能意味着扫描整个进程空间。完成后,上一次扫描未“标记”的所有对象将进入空闲列表(被垃圾回收)。
正如您所看到的,这是一项繁重的操作。
该方法的执行已完成。
因此,您已经超出了调用的方法的范围,因为它已经完成,这一事实是无关紧要的。这并不意味着运行时在那个时候就知道对象已经完成(因为GC是并行运行的)。
这不像在C++中,在方法结束时程序员会调用delete来删除对象,因为它不再需要。在Java中,没有“delete”会在方法结束时自动调用。
GC线程最终会意识到由方法分配在堆上的对象没有更多的引用,并对其进行垃圾回收。
如果您想要,在任何时候都可以通过以下方式调用GC:
System.gc();
但是垃圾回收器迟早会运行。
需要注意的一点是,只要根指针引用了方法,它就不能被垃圾回收器回收。
因此,如果在您的方法中通过new
在堆上创建一个对象,并将引用存储在静态容器中或返回给调用者,则该对象的生命周期超出了该方法。
当从方法调用(System.gc)返回控制时,Java虚拟机已经尽最大努力从所有废弃对象中回收空间
。 - Cratylus