【问题标题】:Life cycle of a new object without reference没有引用的新对象的生命周期
【发布时间】:2015-09-03 01:55:25
【问题描述】:

我的问题与:

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

 (new SomeClass()).longMethod();

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

如果堆栈上没有任何内容,那么垃圾收集器如何知道在方法执行期间保留对象?

可能和

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

【问题讨论】:

  • 听说过this吗?
  • @Ingo - 需要详细说明吗?
  • 先回答。它在方法中是什么?它来自哪里?

标签: java object memory-management garbage-collection jvm


【解决方案1】:

是的,堆栈中存在对新对象的引用。

直接来自甲骨文:

要访问字段,您可以使用对对象的命名引用,如 前面的示例,或者您可以使用任何返回 对象引用。回想一下,new 运算符返回对 一个东西。所以你可以使用从 new 返回的值来访问 新对象的字段:

int height = new Rectangle().height;

这个语句创建了一个新的 矩形对象并立即获取其高度。从本质上讲, 语句计算 Rectangle 的默认高度。 请注意 这条语句执行后,程序不再有 引用创建的 Rectangle,因为程序从未存储过 任何地方的参考。对象未被引用,其资源 可以免费被 Java 虚拟机回收。

来源:https://docs.oracle.com/javase/tutorial/java/javaOO/usingobject.html

【讨论】:

  • 请提供更多证据或示例
  • height 方法可以将this 存储在某处,因此Oracle 并不完全正确。在不知道高度代码的情况下,我们只是不知道引用是否存储在某个地方。
  • @Ingo 好吧,我假设他们的意思是 java.awt.Rectangle,它没有这种行为,但你为一般情况提出了一个很好的观点。
【解决方案2】:

是的,

new SomeClass().longMethod();

实际上是相同的,尤其是从垃圾收集的角度来看:

{
    SomeClass throwAwayRef = new SomeClass();
    throwAwayRef.longMethod();
}

内联版本隐式引用了新对象(在堆栈上)。一旦方法调用完成,它就可用于垃圾回收。

【讨论】:

  • 请注意,这两个 sn-ps 在字节码级别上是不同的,尽管它们在功能上确实是等效的。
  • 它是记录在某处还是留给 JVM 实现?
【解决方案3】:

您可以查看字节码以获得洞察力:

   0: new           #16                 // class SomeClass
   3: dup
   4: invokespecial #18                 // Method SomeClass."<init>":()V
   7: invokevirtual #19                 // Method SomeClass.longMethod:()V
  • new 实际上分配了对象,该对象的引用被压入堆栈。
  • dup 复制栈顶;现在顶部的两个堆栈项是对新创建对象的引用。
  • invokespecial这里调用SomeClass的构造函数,出栈;现在堆栈只包含对我们SomeClass 实例的单个引用。该实例未被 GC,因为堆栈中存在对它的引用。
  • invokevirtual 这里调用longMethod。同样,实例没有被 GC,因为对它的引用仍然存在于堆栈中(并在方法完成后弹出,之后它有资格进行 GC)。

(new SomeClass()).longMethod();

不一样

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

在字节码级别,因为后者涉及astoreaload。但是,两者在功能上肯定是等效的。在longMethod 完成后,SomeClass 实例仍然有资格进行 GC(在执行 invokevirtual 时,两个 sn-ps 的堆栈看起来相同)。


参考:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-28
    相关资源
    最近更新 更多