繁体   English   中英

最终静态与最终非静态字段和JVM优化

[英]final static vs final non-static fields and JVM optimization

我很好奇JVM如何处理static final字段。 我在这里看到了类似的问题但这不是我想要的。 让我们考虑这样的例子:

public class TestClassX {
   public final int CODE_A = 132;
   public final int CODE_B = 948;
   public final int CODE_C = 288;
   // some other code
}

public class TestClassY {
   public static final int CODE_A = 132;
   public static final int CODE_B = 948;
   public static final int CODE_C = 288;
   // some other code
}

TestClassX字段中,由于它们是final且无法修改,因此在TestClassX类的所有实例中具有相同的值。 当然我不能编写TestClassX.CODE_A但我可以说,这些值实际上对所有实例都是通用的 - 我敢肯定,每个实例都有一个值为132CODE_A字段。

TestClassY我可以使用语法TestClassY.CODE_A ,但初看起来,对于看到“哦,这些值对于所有实例都很常见”的开发人员来说,它更容易。

我的主要问题:我猜JVM,在TestClassX情况下,每次创建新实例时都不会为final字段使用任何额外的内存。 可以? JVM是否在这种情况下进行任何优化以及它是什么样的优化?

额外的问题1)我也确信我错过了一些非常重要的东西,这是我怀疑的原因。 那是什么?

额外的问题2)顺便说一句。 如何在JVM优化之后查看我的Java源代码的样子(以便将来可以使用;))? 有没有IDE支持这样的功能? 例如IntelliJ? 我想简单地看看JVM如何处理我的TestClassXTestClassY

  • 非静态字段始终存在于实例中。 他们不节省记忆。
  • 通常,JVM不会优化非静态字段。 即使它们是最终的,它们仍然可以使用反射或反序列化设置为不同的值。
  • 有一个实验性VM选项-XX:+TrustFinalNonStaticFields (默认情况下为off),它告诉JVM优化对这些字段的访问,即将它们视为常量并消除字段负载。
  • 有一个-XX:+PrintAssembly VM选项来转储JIT编译的代码。

对于您问题的第一部分,也许这个答案可以帮助您。

对于第二部分,您可以通过在运行/编译代码时添加-XX:+PrintOptoAssembly标志来查看生成的程序集(如本答案中所述 )。

我还要补充一点,给你的汇编代码不是jvm生成的真正的操作码,但代码需要在你的实际架构下运行。

希望这可以帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM