没有参考的新对象的生命周期 [英] Life cycle of a new object without reference

查看:145
本文介绍了没有参考的新对象的生命周期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题与:





当我们的代码中有这样的东西时会发生什么:

 (new SomeClass())。longMethod(); 

还有某种未命名的(强?)引用指向堆上新创建的对象放在堆栈上?



如果Stack上没有任何内容,那么垃圾收集器如何知道在方法持续时间内保留对象?



是否可能与

相同

  {
//非常本地范围
SomeClass throwAwayRef = new SomeClass();
throwAwayRef.longMethod();
}


解决方案

你可以查看字节码洞察:

  0:new#16 // class SomeClass 
3:dup
4:invokespecial #18 //方法SomeClass。< init>:()V
7:invokevirtual#19 //方法SomeClass.longMethod :()V




  • new 实际分配对象,对象的引用被推送到堆栈。

  • dup 复制堆栈顶部;现在前两个堆栈项是对新创建的对象的引用。

  • invokespecial 这里调用的构造函数SomeClass ,弹出堆栈;现在,堆栈只包含对我们的 SomeClass 实例的单个引用。该实例未进行GCed,因为堆栈上存在对它的引用。

  • invokevirtual 此处调用 longMethod 。同样,实例不是GCed,因为对它的引用仍然存在于堆栈上(并且在方法完成后弹出,之后 符合GC的条件)。






 (new SomeClass())。longMethod(); 



<$ p $不同p> {
//非常本地范围
SomeClass throwAwayRef = new SomeClass();
throwAwayRef.longMethod();
}

字节码级别的

,因为后者涉及 astore aload 。但是,这两者肯定在功能上是等价的。在 longMethod 完成后, SomeClass 实例仍符合GC条件(两个代码段的堆栈在<$时看起来相同) c $ c> invokevirtual 已执行)。






参考:




My question is related to:

What actually happens when we have something like this in our code:

 (new SomeClass()).longMethod();

Is there still some sort of unnamed (strong ?) reference pointing to the newly created object on Heap put on Stack?

If nothing is on Stack, then how does Garbage Collector know to preserve the object for the duration of the method?

Is it possibly the same as

{ 
  // very local scope
  SomeClass throwAwayRef = new SomeClass();
  throwAwayRef.longMethod();
}

解决方案

You can look at the bytecode for insight:

   0: new           #16                 // class SomeClass
   3: dup
   4: invokespecial #18                 // Method SomeClass."<init>":()V
   7: invokevirtual #19                 // Method SomeClass.longMethod:()V

  • new actually allocates the object, a reference to which is pushed on the stack.
  • dup duplicates the top-of-stack; now the top two stack items are references to the newly created object.
  • invokespecial here calls the constructor of SomeClass, popping the stack; now the stack consists of just a single reference to our SomeClass instance. The instance is not GCed because a reference to it exists on the stack.
  • invokevirtual here calls longMethod. Again, the instance is not GCed because a reference to it still exists on the stack (and is popped after the method completes, after which it is eligible for GC).

(new SomeClass()).longMethod();

is not the same as

{ 
  // very local scope
  SomeClass throwAwayRef = new SomeClass();
  throwAwayRef.longMethod();
}

at the bytecode level, since the latter involves an astore and an aload. However, the two are certainly functionally equivalent. The SomeClass instance still becomes eligible for GC after longMethod completes (the stacks for the two snippets will look identical when invokevirtual is executed).


Reference:

这篇关于没有参考的新对象的生命周期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆