在执行Java应用程序期间,是运行时使用的对象引用还是在编译时被删除?
我想我可以反编译类文件,看看它们如何用作局部变量和成员变量。
当您不需要或者编译器是否会删除不需要的引用时,创建对象引用是否浪费?
E.g。
final String abc =“abc”; 法(ABC);
而不是:
方法( “ABC”);
答案 0 :(得分:1)
方法存储在对象数据区域中(如类定义所示),但块本地引用存储在JVM堆栈帧的特殊区域中。当帧从执行线程的帧堆栈中弹出时,所有块本地引用都将丢失,因为它们实际上并未存储在对象的数据结构中。
请注意,如果您不熟悉JVM堆栈帧,则会为每个方法的入口获取新的堆栈帧,并在从方法返回时从Thread的堆栈中弹出。堆栈帧包含许多元素,包括指向当前指令的指针(位于类的指令页面中)指向“this”对象的指针,以及用于保存当前方法计算中间体的小堆栈。有时变量引用不会产生任何存储需求,然后许多优化编译器将编译出代码以使用本地堆栈而不是“对象引用存储”,这意味着反转代码将导致不会发现该人完全使用了一个变量。
“this”指针始终占据对象引用存储区域中的第一个条目,并且所有这些概念都是概念性的。实际实现只需要符合操作标准,不需要符合特定的内存布局。
答案 1 :(得分:0)
在字节码级别,这样的“不必要”引用不会被删除;你可以在字节码中看到上面的赋值。但JIT(即HotSpot)通常更加智能,因此运行时影响基本为零。
答案 2 :(得分:0)
在你提到的特殊情况下,你命名一个局部变量并将其命名为“abc”这一事实对你作为程序员来说基本上是一种便利。无论你是否这样做,或者只是把它作为一个未命名的参数,字节码基本上都会一样。
一般来说,您无需担心这种详细程度。您可以信任字节码编译器和JIT编译器来做出明智的事情。如果你不得不担心这个细节,那么编写任何中等复杂度的应用几乎是不可能的......
[P.S。如果您有时间和兴趣,我还建议您将相应的类反编译为教育练习。但是你会发现你应该非常放心:编译器通常会做出明智的事情并且不需要偏执。]