PM *_*7-1 10 java garbage-collection jvm memory-management object
我的问题与:
当我们在代码中有这样的事情时,实际发生了什么:
(new SomeClass()).longMethod();
Run Code Online (Sandbox Code Playgroud)
是否还有某种未命名的(强?)引用指向堆放在Heap上的新创建的对象?
如果Stack上没有任何内容,那么垃圾收集器如何知道在方法持续时间内保留对象?
它可能是相同的
{
// very local scope
SomeClass throwAwayRef = new SomeClass();
throwAwayRef.longMethod();
}
Run Code Online (Sandbox Code Playgroud)
您可以查看字节码以获得洞察力:
0: new #16 // class SomeClass
3: dup
4: invokespecial #18 // Method SomeClass."<init>":()V
7: invokevirtual #19 // Method SomeClass.longMethod:()V
Run Code Online (Sandbox Code Playgroud)
new 实际上是分配对象,对象的引用被推送到堆栈上. dup复制堆栈顶部; 现在,前两个堆栈项是对新创建的对象的引用.invokespecial这里调用构造函数SomeClass,弹出堆栈; 现在堆栈只包含对我们SomeClass实例的单个引用.该实例未进行GCed,因为堆栈上存在对它的引用.invokevirtual在这里呼吁longMethod.再次,该实例不是GCed因为对它的引用在栈上仍然存在(并且该方法完成之后,在这之后被弹出是获GC).(new SomeClass()).longMethod();
Run Code Online (Sandbox Code Playgroud)
是不一样的
{
// very local scope
SomeClass throwAwayRef = new SomeClass();
throwAwayRef.longMethod();
}
Run Code Online (Sandbox Code Playgroud)
在字节码级别,因为后者涉及a astore和a aload.但是,这两者肯定在功能上是等价的.完成后,SomeClass实例仍然符合GC条件longMethod(两个代码段的堆栈在invokevirtual执行时看起来相同).
参考:
是的,对新对象的引用存在于堆栈中。
直接来自甲骨文:
要访问字段,您可以使用对象的命名引用(如前面的示例所示),也可以使用返回对象引用的任何表达式。回想一下,new 运算符返回对对象的引用。因此,您可以使用 new 返回的值来访问新对象的字段:
int height = new Rectangle().height;该语句创建一个新的 Rectangle 对象并立即获取其高度。本质上,该语句计算矩形的默认高度。请注意,执行此语句后,程序不再拥有对创建的 Rectangle 的引用,因为程序从未在任何地方存储该引用。该对象是未引用的,其资源可以由 Java 虚拟机自由回收。
来源: https: //docs.oracle.com/javase/tutorial/java/javaOO/usingobject.html
| 归档时间: |
|
| 查看次数: |
2606 次 |
| 最近记录: |