【Java】運行時Java對象在內存中是如何存儲的?


翻譯自這一篇文章

我們知道函數在內存中實現為一個活動記錄的棧。我們也知道Java方法在JVM棧區中實現為一個幀棧而Java對象是在堆區進行分配的。

Java對象在堆內存中是怎樣的呢?一旦對象保存在內存中,就只是字節序列。

那么我們如何知道去哪里查找某個字段?在編譯器內部保留一個內部表,來記錄每個字段的偏移量。

下面的例子,是關於類“Base”(B)的對象布局。這個類中沒有任何方法,類方法在內存中的存儲方法會在下一節說到。

base

如果我們有一個類“Derived”(D)繼承了這個“Base”類。那么內存分布就如下

derived

子對象有着與父對象相同的內存分布,只不過它還需要多一些的空間來存放新增的成員。這種布局方式的好處在於,一個B類型的指針指向D對象時,仍然可以在內存區域的開始部分找到B對象。因此,通過B引用來對D對象進行操作都保證是安全的,從而也就不必動態地檢查B指向的是什么。

按照同樣的邏輯,方法可以被放在對象的開頭處。

methods

不過,這個方法效率不高。如果一個類中有很多方法(比如說,M個),那么每個對象都必須有O(M)的指針集。此外,每一個對象都需要有可容納O(M)指針的空間。這些要求使得創建對象更慢而對象占用更大。

最佳是方法就是去創建一個虛函數表,這是一個指針數組,其中的指針指向某個類的具體成員函數實現。為每一個類創建一個虛函數表的實例,並在每個對象中保存一個指向虛函數表的指針。

optimization

這個就是最優化的方法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM