通過dump分析Java對象在內存中到底佔用多大空間?

一、內存結構分析
1、概念:
Shallow Size:Shallow size就是對象本身佔用內存的大小,不包含其引用的對象。
retained size: 自身對象+引用對象的retained大小。
2、jvm內存創建對象組成部分
1)對象頭包括兩部分:
第一部分markword,用於存儲對象自身的運行時數據,如哈希碼(HashCode)、GC分代年齡、鎖狀態標誌、線程持有的鎖、偏向線程ID、偏向時間戳等
第二部分類型指針,虛擬機通過這個指針來確定這個對象是哪個類的實例
2)實例數據
實例數據部分是對象真正存儲的有效信息,也是在程序代碼中所定義的各種類型的字段內容。無論是從父類繼承下來的,還是在子類中定義的,都需要記錄起來。
3)填充數據
最後一塊對齊填充空間並不是必然存在的,也沒有特別的含義,它僅僅起着佔位符的作用。這是由於HotSpot VM的自動內存管理系統要求對象起始地址必須是8字節的整數倍,換句話說,就是對象的大小必須是8字節的整數倍。
3、對象頭佔用空間
1. 在32位系統下,存放Class引用指針的空間大小是4字節,MarkWord是4字節,對象頭爲8字節。
2. 在64位系統下,存放Class引用指針的空間大小是8字節,MarkWord是8字節,對象頭爲16字節。
3. 在64位開啓指針壓縮的情況下 -XX:+UseCompressedOops,存放Class引用的空間大小是4字節,MarkWord是8字節,對象頭爲12字節。
4. 如果對象是數組,需要另外增加4字節,用來記錄數組長度,也就是一個int類型的對象,佔4字節
二、確認機器環境情況:
查看機器位數
java -d64 -version

 

查看是否開啓壓縮
jinfo -flag UseCompressedOops 462238
目前機器JVM內存情況
 
三、對象佔用內存分析及優化實戰
1、dump內存文件是使用JProfiler分析
2、內存具體情況分析
1)int[]數組佔用內存空間分析:
 對象頭12byte+2*4數據+ 4(記錄數組長度) = 24byte
 
2)字符串分析:
單純一個String: 的shallowSize 24byte= 對象頭(8+4)byte+4byte(字段屬性hash)+8byte(long序列號號) 
單純一個char[] 內存大小shallowSize  16 btype = 對象頭(8+4)byte+4byte(數組長度)
一個String最小佔用內存:40Byte
一個String佔用內存大小Retained = (shallowSize 24byte) +( char[] 的shallowSize  16 btype) +一個char 2byte*N個字符 = 40 +2N + (40 +2N)/8,然後補齊到8的倍數(40 +2N)/8。其中N是字符個數
如規則adowner = 40+2*10 + (40+2*10)/8 = 64
 
 
3)Long佔用內存分析
Long 24  = 12Byte(對象頭)+8btype + 4byte(對齊補充) 
 
3、優化點
1)時間字符串優化成 int,佔用內存效果:64byte->4byte  降低原來 1/16
2)hashMap的key由String 優化成Long,內存佔用優化效果:72byte->24byte  降低原來 1/3
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章