標籤:int 屬性 img 部落格 空間 port sdn compress tail
近期在寫一個C++ 和java的socket通訊程式。須要把收到的位元組流轉存到一個對象,引申出了這個問題,尋找了一些網上的資料,總結例如以下
本文僅僅包括簡單java對象的記憶體布局,不考慮繼承的情況
Java類的一個執行個體在記憶體中包括 對象頭,非待用資料成員和對齊資料。
待用資料成員,方法成員為類的全部執行個體共用。不儲存在某個對象執行個體裡。
對象頭的大小取決于于JVM的實現。同一個JVM,普通對象,數組對象。內部對象的對象頭大小又有差別。
基礎資料型別 (Elementary Data Type)的大小JVM規範有明白定義,但參考型別在32bit JVM下是4位元組,64bit JVM下是8位元組(不啟用指標壓縮參數UseCompressedOops)。
32bit JVM 和 64bit JVM一般都是8位元組(64 bit)對齊。
一個64bit JVM裡面一個基本對象記憶體布局可能例如以下所看到的
數組對象的對象頭是24位元組,除去16位元組基本資料,再加4位元組長度資料。4位元組對齊資料。另外。對象數組的每個元素儲存的是對象的引用。
非靜態內部對象的對象頭也是24位元組。16位元組的基本資料,加上一個外部類的引用8位元組,64bit JVM是8位元組,32bit JVM 是4位元組加上對齊資料4位元組。
假設對象的成員中,含有其它對象比方數組,字串,這個對象僅僅儲存這些成員對象的引用,這些成員對象的記憶體並不直接包括在這個對象的記憶體中,在它之外。
非靜態成員在對象記憶體中的位置和聲明順序是一致的嗎?未必
我尋找到了一篇相關部落格,寫於2008年http://www.importnew.com/1305.html
裡面提到 Sun VM(如今已經是Oracle VM了,。。)並沒有依照屬性聲明時的順序進行記憶體布局,為了節省記憶體採用了下面順序
1. 雙精確度型(doubles)和長整型(longs)
2. 整型(ints)和浮點型(floats)
3. 短整型(shorts)和字元型(chars)
4. 布爾型(booleans)和位元組型(bytes)
5. 參考型別(references)
這篇部落格提到了5個規則
規則1:不論什麼對象都是8個位元組為粒度進行對齊的。
規則2:類屬性依照例如以下優先順序進行排列:長整型和雙精確度類型。整型和浮點型;字元和短整型;位元組類型和布爾類型,最後是參考型別。這些屬性都依照各自的單位對齊。
規則3:不同類繼承關係中的成員不能混合排列。首先依照規則2處理父類中的成員。接著才是子類的成員。
規則4:當父類中最後一個成員和子類第一個成員的間隔假設不夠4個位元組的話,就必須擴充到4個位元組的基本單位
規則5:假設子類第一個成員是一個雙精確度或者長整型。而且父類並沒實用完8個位元組。JVM會破壞規則2。依照整形(int),短整型(short)。位元組型(byte),參考型別(reference)的順序,向未填滿的空間填充。
所以這個規則還是比較複雜的
這篇部落格寫於2008年。JVM的實現非常可能已經變化,並且JVM版本號碼眾多,瞭解這麼多各自的規範是一件比較麻煩的事,從有用的角度來說,能夠僅僅瞭解某個對象的布局
openJDK提供了一個工具。能夠查看對象的記憶體布局,這篇部落格裡面介紹了這個工具http://blog.csdn.net/aitangyong/article/details/46416667,能夠使用這個工具進行分析。
說明:
本文由giantpoplar發表於CSDN
文章地址 http://blog.csdn.net/giantpoplar/article/details/47657377
轉載請保留本說明
Java對象的記憶體布局