關於Java對象內存結構

我們知道,函數每次被調用時,在內存中都有自己的活動記錄(activation record),稱為棧空間(stack). Java 的方法在調用時在 JVM 棧中為其分配一個棧幀(Java棧空間的一個片段),可以稱之為方法棧. 原則上,所有對象都在堆空間(Heap)中分配。

關於Java對象內存結構

java對象在內存中是怎樣分配的呢? 一旦對象在堆中分配了空間,那本質上就是一系列的字節. 那麼如何找到對象中某個特定的屬性域呢? 編譯器通過一個內部表來保存每個域的偏移量。

Java中並沒有一個類似的運算符。事實上,Java也不需要這種運算符。Java中基本類型的大小在語言規範中已經定義了,而C/C++中基本類型大小則跟平臺相關。Java有自己的通過序列化構建的IO框架。再者,由於Java中沒有指針,因此指針運算和內存塊拷貝之類的操作也不存在。

關於Java對象內存結構

使用用戶線程的優勢在於不需要系統內核的支援,劣勢在於沒有系統內核的支援,所有的線程操作都需要用戶程序自己處理,因而使用用戶線程實現的程序一般都比較複雜,現在使用用戶線程的程序越來越少了。Java、Ruby層語言都曾經使用過用戶線程,最終又都放棄了使用它。

混合實現

混合環境下,既存在用戶線程,又存在輕量級進程。用戶線程還是完全建立在用戶空間中,而操作系統所支持的輕量級進程則作為用戶線程和內核線程之間的橋樑。這種混合模式下,用戶線程與輕量級進程的數量比是不定的,是M:N的關係。許多Unix系列的系統,都提供了M:N的線程模型實現。

任何對象都是8個字節為粒度進行對齊的。

比如,如果調用new Object(),由於Object類並沒有其他沒有其他可存儲的成員,那麼僅僅使用堆中的8個字節來保存兩個字的頭部即可。

關於Java對象內存結構

繼承了Object的類的內存佈局

除了上面所說的8個字節的頭部,類屬性緊隨其後。屬性通常根據其大小來排列。例如,整型(int)以4個字節為單位對齊,長整型(long)以8個字節為單位對齊。這裡是出於性能考慮而這麼設計的:通常情況下,如果數據以4字節為單位對齊,那麼從內存中讀4字節的數據並寫入到處理器的4字節寄存器是性價比更高的。

尚學堂立志解決中國教育不公平和低效率問題,幫助千千萬萬被傳統教育方式耽誤的人,傳授實用、前沿的知識,成就學員個人理想,為愛你的人和你愛的人創造美好的生活。尚學堂12大精英團隊+各類實戰項目,真正實現1+1>10的目標效果。幫助學員迅速成長,持久騰飛,成就學員“高富帥”人生。


分享到:


相關文章: