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

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

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

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

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

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

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

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

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

对象生命周期

java程序从不同的类创建许多对象。 Java中的对象,通过相互发送消息进行交互。 在完成处理之后,这些对象随后被垃圾收集。 在垃圾收集过程之后,操作系统声明分配给这些对象的资源,这些资源将被新对象进一步使用。

以下是Java对象在其生命周期中经历的阶段:

1.class级装载

在从类创建对象之前,应该从磁盘将类加载到内存中。 java类加载器将类文件加载到内存中。

上课的时候?

  • 第一次创建对象时

  • 首次访问任何静态字段或方法。

静态初始化器

Java查找任何静态初始值设定项并初始化静态字段,这些字段是类的一部分,而不是类(对象)的特定实例的一部分。

3.对象创建

Object是类的一个实例。 它是在以下情况下创建的:

声明:声明对象时,例如ClassA objA; 实例化:当new用于在堆内存中分配新对象时,例如new ClassA(); 初始化:构造新对象,例如ClassA(); 4.对象的用法

在这个阶段,程序可以通过访问字段或调用方法来使用该对象。

5.清理

这是Java对象的最后阶段,它们被回收并且操作系统声明了内存。

毁灭会发生什么?

对象从内存中删除。 Java删除了对此对象的内部引用。 垃圾收集(GC),运行释放不再需要的对象,即没有对此对象的引用。 完成:GC通过调用其finalize()方法为对象提供了清理任何其他资源的最后机会。

什么时候发生?

当对象超出范围时。 即{… objA …},这里}成为范围。 此时,Java运行时检查引用并让GC回收此对象。 当java运行时内存中对该对象的引用数变为零(0)时。 当object显式设置为null,即objA = null;时,GC被称为finalize()方法被显式调用。

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

该方法的执行已完成。

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

System.gc(); 

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