2009-09-15 87 views
9

在Java中,如果我創建了一個Hashtable<K, V>並將N個元素放入其中,它將佔用多少內存?如果它依賴於實現,那麼什麼是一個好的「猜測」?Hashtable使用多少內存?

+0

它可能會被你的鍵和值對象的大小所佔據(小地圖除外)。 – 2009-09-15 09:32:23

+0

我已經添加了一個精確的計算,但它可能會隨着虛擬機而變化。 這並非總是如此。使用非常小的鍵和值(例如,對於基元的包裝對象),Entry對象的大小可能會佔據散列表/散列表的大小(在內部它們是相同的)。如果多個值是對同一個對象實例的引用,也會發生這種情況。 如果您使用很多原始對象作爲鍵或值,請查看Trove庫。這對於更快,更高效的內存。 – BobMcGee 2009-09-15 15:49:13

回答

12

編輯; 哦,geez,我是個白癡,我給了HashMap的信息,而不是HashTable。但是,在檢查之後,實現對於存儲目的是相同的。

這取決於您的虛擬機的內部存儲器設置(包裝項目,32位或64位指針,以及字對齊/大小),並未由java指定。

估算記憶體使用的基本信息可以在here找到。

可以估算它像這樣:

  • 在32位的虛擬機,一個指針是4個字節,在64位的虛擬機,它是8個字節。
  • 對象開銷是8個字節的內存(對於空對象,不包含任何內容)
  • 對象被填充爲8字節(ugh)倍數的大小。
  • 每個散列圖有一個小的,不變的開銷:一個浮點數,3個整數,加上對象開銷。
  • 有一組插槽,其中一些插槽會有條目,其中一些將保留給新的插槽。已填充插槽與總插槽的比例不超過構造函數中指定的加載因子。
  • 槽陣列需要一個對象開銷,加上一個int大小,再加上一個指針,以指示存儲的對象。
  • 槽的數量通常是存儲映射的數量的1.3到2倍,默認加載因子爲0.75,但可能會小於此值,具體取決於散列衝突。
  • 每個存儲的映射都需要一個入口對象。這需要一個對象開銷,3個指針,加上存儲的鍵和值對象,加上一個整數。

因此,把它在一起(32/64位Sun的HotSpot JVM): HashMap中需要24個字節(本身,本原字段)+ 12字節(縫隙陣列常數)每時隙+ 4或8個字節+每個條目+密鑰對象大小+值對象大小+填充24/40字節每個對象的8個字節

OR,大致多個(至多默認設置,但不保證精確):

  • 在32位JVM:36個字節+ 32字節/映射+鍵&值
  • 在64位JVM:36個字節+ 56字節/映射+鍵&值

注:此需要更多的檢查,它可能需要12個字節用於64位VM上的對象開銷。 我不確定關於空值 - 空值的指針可能會以某種方式壓縮。