在方法调用期间创建的本地Java对象的生命周期

时间:2010-12-29 19:34:42

标签: java garbage-collection

在方法调用中,如果我在该调用期间创建了一个对象。这些对象何时被垃圾收集?

它们是否放在堆上,然后将垃圾与堆上的其他对象一起收集。或者他们之前是垃圾收集,因为他们不需要。该方法的执行已经完成。

3 个答案:

答案 0 :(得分:6)

方法范围内创建的对象在方法关闭时有资格进行垃圾回收 - 除非该引用作为返回值传回。在这种情况下,调用者可能会或可能不会挂在该引用上并阻止它被gc'd。

由于垃圾收集器根据自己的灯光在自己的线程上运行,因此您不一定知道何时清理对象,或者其他地方分配的对象是否也符合条件。

答案 1 :(得分:3)

这并不容易 - 最后在某个方法中创建了每个对象。

VM /编译器需要进行转义路径分析以检测此对象的引用是否可以以某种方式转义 - 想象一下调用newObject.toString()。你和我知道(希望)这不会造成伤害,并且仍然没有引用该对象,因为它不会将自身链接到全局变量。但虚拟机没有显示出来。

虽然现代VM将进行此类分析并处理垃圾收集中特殊的真实短期对象,但从“高级”角度来看,它们只是对象。其他一切都是复杂的低级优化。

无论如何,正如duffymo所说 - 当这些物体被释放时,这是不确定的。

答案 2 :(得分:1)

方法的执行已经结束并且现在对象超出范围的事实是无关紧要的 垃圾收集是运行时系统的隐式操作,它在与您的代码并行的单独线程中运行,实现特定的垃圾收集算法。
垃圾收集线程在不可预测的时间运行 - 但是很多时候,根据java文档每隔一秒左右运行一次,当内存几乎耗尽时,评估哪些对象有资格被垃圾收集,即根本没有从根指针引用它们,例如静态变量。
因此,根指针可访问的每个对象都被标记,然后递归地标记这些对象引用的对象等 这可能意味着扫描整个过程空间。完成后,所有未从之前扫描中“标记”的对象都会进入空闲列表(GC'd) 你可以看到这是一个繁重的操作。

  

该方法的执行具有   完成。

因此,事实上你已经超出了你所调用的方法的范围,因为它已经完成,这是无关紧要的。这并不意味着运行时知道该对象已完成(因为GC并行运行) 它不像在C ++中那样,在方法的最后,程序员会在对象上调用delete,因为它不需要。在Java中,在方法结束时不会自动调用“delete” GC线程最终将意识到该方法和CG不再引用堆上分配的对象 如果需要,您可以随时致电GC:

System.gc();

但无论如何,GC迟早会运行 需要注意的一点是,只要根指针引用方法就不能成为GC的 因此,如果在您的方法中通过new在堆上创建对象并将引用存储在静态容器中或将其返回给调用者,则该对象比该方法更长。