繁体   English   中英

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

[英]Life cycle of local Java objects created during a method call

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

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

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

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

这不是那么容易 - 最后,每个对象都是以某种方法创建的。

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

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

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

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

该方法的执行已完成。

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

System.gc();

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM