2011-03-17 68 views
1

執行Java應用程序期間,運行時使用的對象引用還是在編譯時被剝離?使用Java VM,如何處理對象引用

我想我可以反編譯的類文件,看看它們是如何使用的局部變量和成員變量。

是不是浪費創建一個對象引用,當你不需要或將編譯器部分去掉不必要的參考?

例如

final String abc =「abc」;方法(abc);

,而不是:

方法( 「ABC」);

回答

1

的方法是存儲在對象數據區(如由類定義佈局),但阻止局部引用存儲在JVM堆棧幀的一個特殊的區域。當框架從執行線程的框架棧中彈出時,所有塊本地引用都會丟失,因爲它們實際上並不存儲在對象的數據結構中。

請注意,如果您不熟悉JVM堆棧幀,爲進入每一個方法得到一個新的堆棧幀,並且從方法返回時被彈出線程的堆棧。堆棧幀包含許多元素,包括指向當前指令(位於類的指令頁面)的指針,指向「this」對象的指針以及用於保存當前方法計算中的中間值的小堆棧。有時,變量引用不會產生任何存儲需求,並且許多優化編譯器將編譯出代碼來使用本地堆棧,而不是「對象引用存儲」,這意味着反轉代碼將導致無法發現該人員根本就使用了一個變量。

的「this」指針總是佔據在對象引用存儲區域中的第一個條目,並且所有的這些概念是概念性的。實際的實現只需要符合操作標準,不需要符合特定的內存佈局。

0

在字節碼級,這樣的「不必要」的引用將不會被剝離出去;您可以在字節碼中看到上述分配。但是JIT(即HotSpot)通常更智能,所以運行時影響基本上爲零。

0

在你提到的特定情況下,你命名一個局部變量並將其命名爲「abc」的事實對於程序員來說基本上是一種方便。不管你是否這樣做,或只是將它作爲一個未命名的參數,字節碼將基本上結束。

一般而言,您無需擔心該詳細程度。你可以信任字節碼編譯器和JIT編譯器來做明智的事情。如果你不得不擔心這個細節水平,那麼寫出任何適度複雜的應用程序實際上是不可能的......

[P.S.如果你有時間和興趣,我還建議你做一個教育練習來反編譯相應的類。但是,你會發現應該很放心:編譯器通常做出明智的事情,並且不需要偏執狂。]