使用Java VM,如何处理对象引用

时间:2011-03-17 19:46:54

标签: java object jvm vm-implementation

在执行Java应用程序期间,是运行时使用的对象引用还是在编译时被删除?

我想我可以反编译类文件,看看它们如何用作局部变量和成员变量。

当您不需要或者编译器是否会删除不需要的引用时,创建对象引用是否浪费?

E.g。

final String abc =“abc”; 法(ABC);

而不是:

方法( “ABC”);

3 个答案:

答案 0 :(得分:1)

方法存储在对象数据区域中(如类定义所示),但块本地引用存储在JVM堆栈帧的特殊区域中。当帧从执行线程的帧堆栈中弹出时,所有块本地引用都将丢失,因为它们实际上并未存储在对象的数据结构中。

请注意,如果您不熟悉JVM堆栈帧,则会为每个方法的入口获取新的堆栈帧,并在从方法返回时从Thread的堆栈中弹出。堆栈帧包含许多元素,包括指向当前指令的指针(位于类的指令页面中)指向“this”对象的指针,以及用于保存当前方法计算中间体的小堆栈。有时变量引用不会产生任何存储需求,然后许多优化编译器将编译出代码以使用本地堆栈而不是“对象引用存储”,这意味着反转代码将导致不会发现该人完全使用了一个变量。

“this”指针始终占据对象引用存储区域中的第一个条目,并且所有这些概念都是概念性的。实际实现只需要符合操作标准,不需要符合特定的内存布局。

答案 1 :(得分:0)

在字节码级别,这样的“不必要”引用不会被删除;你可以在字节码中看到上面的赋值。但JIT(即HotSpot)通常更加智能,因此运行时影响基本为零。

答案 2 :(得分:0)

在你提到的特殊情况下,你命名一个局部变量并将其命名为“abc”这一事实对你作为程序员来说基本上是一种便利。无论你是否这样做,或者只是把它作为一个未命名的参数,字节码基本上都会一样。

一般来说,您无需担心这种详细程度。您可以信任字节码编译器和JIT编译器来做出明智的事情。如果你不得不担心这个细节,那么编写任何中等复杂度的应用几乎是不可能的......

[P.S。如果您有时间和兴趣,我还建议您将相应的类反编译为教育练习。但是你会发现你应该非常放心:编译器通常会做出明智的事情并且不需要偏执。]