天天看點

hashmap 不釋放空間_一個1000萬HashMap,會占用多少空間記憶體?

問題

一個1000萬HashMap,會占用多少空間記憶體?其中,Key=String(長度不超過16字元,且重複性極小),Value=Integer

HashMap記憶體主要組成部分

table 數組所占記憶體

table 中的每個元素 Entry 所占記憶體

假設

為了友善統計,我們做如下假設:

Key hash 之後的結果完全不重複(單個 bucket 最多一條記錄)。

loadFactor = 0.75 (預設值)。

JDK 版本:

hashmap 不釋放空間_一個1000萬HashMap,會占用多少空間記憶體?

64位JVM,本來reference應該是8byte,但是對象指針壓縮XX:+UseCompressedOops預設就是開啟的,reference變為4byte。

Java對象記憶體布局

對象頭(header) + 執行個體資料 + padding(align)

對象頭大小:16byte,預設開啟對象指針壓縮之後,變為為12byte。

padding(align):8byte對齊。

table數組所占空間

存放1千萬記錄,經過多次 resize 之後:table.length() = 16777216

table 數組所占用空間為 = 16777216 * 4(數組的每一項都是一個Entry引用) + 16 (java arrays header size) = 67108864 + 16 = 67108880

Entry空間統計

hashmap 不釋放空間_一個1000萬HashMap,會占用多少空間記憶體?

不考慮reference,單個Entry對象所占空間為:32

reorder 之後的順序如下:

object header size = 12

int hash =  4

reference key = 4

reference value =  4

reference next =  4

padding(align)= 4

然後 key 所占空間:72

String

object header size = 12

int hash = 4

int hash32 = 4

reference value[] = 4char[]

arrays header size = 16

char[] = 16 * 2 (一個字元兩個位元組  utf - 16)

value 所占空間:16

Integer

object header size = 12

int value = 4

1千萬記錄對應1千萬個 Entry 對象,占用總空間為: 10000000 * (32 + 72 + 16) = 1200000000

總的空間

67108880 + 1200000000 = 1267108880 / 1024 * 1024 = 1208M

參考