簡體   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