簡體   English   中英

所有鍵都帶有單字節[]數組的Java哈希映射

[英]Java hashmap with single byte[] array for all keys

我有一個相當大的數據集,包含2.3GB的數據,分布在1.6億個byte []數組中,平均數據長度為15個字節。 每個byte []鍵的值只是一個int,因此幾乎一半的hashmap(超過6GB)的內存使用量由每個字節數組的16字節開銷組成

開銷= 8字節標頭+ 4字節長度由VM向上舍入到16字節。

所以我的開銷是2.5GB。

有沒有人知道一個hashmap實現,它將(可變長度)byte []鍵存儲在一個單個大字節數組中,這樣就沒有開銷(除了1個字節的長度字段)?

我寧願不使用內存數據庫,因為與我正在使用的普通Trove TObjectIntHashMap相比,它們通常具有性能開銷,而且我更重視CPU周期甚至更多的內存使用。

提前致謝

由於目前大多數個人計算機的容量為16GB,服務器通常為32-128GB或更多,因此存在一定程度的簿記開銷存在問題嗎?

如果我們考慮替代方案:將字節數據連接成一個大型數組 - 我們應該考慮單個值看起來是什么樣的,以引用更大數組的切片。

最常見的是你會從:

public class ByteSlice {
    protected byte[] array;
    protected int offset;
    protected int len;
}

但是,這是8個字節+指針的大小(可能只有4個字節?)+ JVM對象頭(64位JVM上的12個字節)。 所以也許總共24個字節。

如果我們嘗試制作這個單一目的和極簡主義者,我們仍然需要4個字節的偏移量。

public class DedicatedByteSlice {
    protected int offset;
    protected byte len;

    protected static byte[] getArray() {/*somebody else knows about the array*/}
}

這仍然是5個字節(可能填充到8)+ JVM對象頭。 可能仍然總共20個字節。

看起來用偏移和長度解除引用並且具有跟蹤它的對象的成本並不比直接存儲小陣列的成本低得多。

另一個理論上的可能性 - 對Map Key進行解構,使其不是一個對象

可以設想對“長度和偏移”數據進行解構,使得它不再存在於對象中。 然后它作為一組標量參數傳遞,例如(長度,偏移),並且 - 在散列圖實現中 - 將通過單獨組件的數組(例如,而不是單個Object [] keyArray)存儲。

但是我希望任何庫都不太可能為你的(非常特殊的)用例提供現有的hashmap實現。

如果你在討論這些可能毫無意義,因為Java不提供多個返回或方法OUT參數; 這使得通信變得不切實際而沒有將結構化數據“裝箱”回到對象。 因為在這里你特別詢問Map鍵,並且這些作為參數傳遞但不需要返回,理論上可以考慮這種方法。

[擴展]即使這樣也變得棘手 - 對於你的用例,地圖API可能必須變得不對稱的人口與查找,因為人口必須通過(偏移,len)來定義密鑰; 而實際查找可能仍然是由具體的byte []數組。

OTOH:即使很舊的筆記本電腦現在也有16GB。 你寫這篇文章的時間(維持4-10次)應該遠遠超過額外RAM的小成本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM