JVM对象占用内存计算
大家都知道,jvm中對象實例存儲在堆中,對象的引用存儲在棧中,而對象的元數據(類型數據)存儲在方法區(qū)。在我們進行內存優(yōu)化的過程中經常需要了解每個對象占用的內存大小。接下來我將介紹對象占用內存大小的計算方式。
Java的對象模型
java是面向對象的語言,每個對象都屬于某個類。在HotSpot虛擬機中對象采用的是oop-klass模型。其實原理很簡單:就是在方法區(qū)中生成一個Class類保存類信息(Klass),包含靜態(tài)常量、靜態(tài)方法、字節(jié)碼、即時編譯代碼等元數據,而在堆中實例化該類的實例對象(oop),實例對象中保存了指向Class類的指針,這樣便構成了oop-klass模型。這樣做有一個好處就是:在實現多態(tài)時只需要在Class類中保存虛方法表來減少頻繁的方法搜索,而實例對象無需保存虛方法表。
每個對象都有一個 mark work 頭部,以及一個引用(klass pointer)指向Class類的信息。
java對象在內存中模型如下:
Java對象內存占用
對象大小分為:
如上圖例子所示:myClass 實例創(chuàng)建出來之后,在內存中所占的大小就是 myClass 自身大小(Shadow heap size)。包括類的頭部大小以及一個int的大小和一個引用的大小。myClass 中object 成員變量是一個對象引用,這個被引用的對象也占一定大小。myClass 實例所維護的引用的對象所占的大小,稱為myClass實例的Retained heap size。我們這里僅討論如何計算對象自身的大小,引用對象大小的計算方式可依此類推。
java對象內存可分為:頭部 + 數據 + 對齊字節(jié)
±-----------------±-----------------±----------------- ±--------------+
| mark word | klass pointer | data (opt) | padding |
±-----------------±-----------------±------------------±--------------+
(1)頭部大小(mark word + klass pointer)
(2)數據大小(data)
空對象不包含任何成員變量,其大小即對象頭大小。若存在成員成員,為了內存緊湊,成員在內存中的排列和聲明的順序可能不一致,這樣才能充分利用內存空間。這是因為在32位系統(tǒng)中,對象大小需要為4byte(32位)的整數倍,而在64位的系統(tǒng)中,對象需要為8byte(64位)的整數倍。如下例子:
其內存布局為:
值得一提的是,數組對象和普通對象存在一點小區(qū)別:數組多一個記錄數組長度的 int 類型(4byte)
總結
以上是生活随笔為你收集整理的JVM对象占用内存计算的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IDEA常用快捷键【win-mac对比】
- 下一篇: cherry-pick的用法