java - 没有引用的新对象的生命周期

标签 java object memory-management garbage-collection jvm

我的问题是:

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

 (new SomeClass()).longMethod();

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

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

有没有可能和

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

最佳答案

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

   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();
}

在字节码级别,因为后者涉及一个astore 和一个aload。但是,两者在功能上肯定是等价的。 longMethod 完成后,SomeClass 实例仍然符合 GC 条件(当执行 invokevirtual 时,两个片段的堆栈看起来相同)。


引用:

关于java - 没有引用的新对象的生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30898219/

相关文章:

c++ - 如何在 C++ 中排序和显示对象列表?

java - 用户的输入可以用于将对象添加到数组中吗?

java - 在 Stringtokenizer 中使用句号作为字符串分隔符

java - 使用 Regex 修复 Java 中未转义的 XML 实体?

javascript - 如何让用户输入变量名?

c# - 什么导致 .NET 中的内存碎片

处理类对象的 MATLAB 弱引用

java - 无法使用版本 4 生成范围报告

java - Java 中的字符串实习

c++ - 为什么不鼓励在堆上创建 std::string/std::map?