试验ConcurrentHashmap
我正在研究我最近的一個項(xiàng)目中的內(nèi)存問題,該項(xiàng)目將數(shù)據(jù)保留在內(nèi)存中以進(jìn)行快速訪問,但是應(yīng)用程序的內(nèi)存占用量非常大。
該應(yīng)用程序大量使用CHM(即Concurrenthashmap) ,因此,無需再費(fèi)腦筋地猜測CHM是問題所在。 我進(jìn)行了一個內(nèi)存分析會話,以了解CHM實(shí)際占用了多少內(nèi)存。
我對結(jié)果感到驚訝,CHM占用了大約50%的內(nèi)存。 因此,可以確定CHM是問題所在,它速度很快,但內(nèi)存效率不高。
為什么CHM這么胖?
- 鍵/值由Map.Entry對象包裝,這為每個對象創(chuàng)建了一個額外的對象。
- 每個段都是一個可重入鎖,因此,如果您有很多小的CHM且默認(rèn)為并發(fā)級別,則將有很多鎖對象,并且該對象將排在首位。
- 還有更多的州開展家政活動。
上述所有對象都對內(nèi)存消耗做出了很好的貢獻(xiàn)。
我們?nèi)绾螠p少內(nèi)存占用
如果很難減少CHM的內(nèi)存占用量,我想到的一些可能原因是
- 它必須支持Map的舊界面
- Java映射使用的哈希碼沖突技術(shù)是封閉哈希 。 封閉式散列基于在沖突時創(chuàng)建鏈接列表,封閉式散列對于解決問題非常快,但它對CPU緩存不友好,尤其是當(dāng)節(jié)點(diǎn)進(jìn)入較大的鏈接列表時。 關(guān)于LinkList問題有一篇有趣的文章
因此,我們需要一種內(nèi)存效率高的替代CHM實(shí)現(xiàn)。
CHM版本2
我開始創(chuàng)建具有低內(nèi)存占用量的CHM版本,目標(biāo)是盡可能接近數(shù)組。 我還使用了替代的哈希碼沖突技術(shù)來檢查性能, Open_addressing有很多選項(xiàng)
我嘗試了以下選項(xiàng):
- 線性探測 –性能并不是那么好,盡管這是最友好的CPU緩存。 需要花費(fèi)更多的時間來解決問題。
- Double_hashing –性能在可接受的范圍內(nèi)。
讓我們測量CHM V2
- 內(nèi)存占用
在內(nèi)存方面有很大的收獲,CHM比原始數(shù)據(jù)多花了大約45%+,新實(shí)現(xiàn)的LCHM非常類似于Array類型。
- 單線程PUT性能
CHM在PUT測試中的表現(xiàn)勝過新產(chǎn)品,對于100萬個項(xiàng)目,新實(shí)施的速度要慢50到80毫秒。 50到80 ms并不是明顯的延遲,我認(rèn)為這對延遲要求以秒為單位的應(yīng)用程序來說是很好的。 如果延遲要求以毫秒/納秒為單位,則CHM的任何方式都不是一個好的選擇。 LCHM性能較慢的原因是哈希沖突技術(shù),雙哈希用于解決有代碼沖突的問題。
- 并發(fā)添加性能
當(dāng)使用多個線程來寫入映射時,新實(shí)現(xiàn)的性能稍好。
- 取得成效
與CHM相比,GET的性能略慢。
結(jié)論
新的實(shí)現(xiàn)在內(nèi)存測試中表現(xiàn)出色,并且在獲取/輸出測試中有點(diǎn)慢。 有幾件事情可以做,以提高獲取/輸出的性能,我們看到的所有性能差異都?xì)w因于所使用的探測技術(shù)。
- 可以改進(jìn)探測技術(shù),可以使用線性探測技術(shù)來獲取緩存友好的訪問。
- 使探測技術(shù)并行化非常容易。
翻譯自: https://www.javacodegeeks.com/2013/05/experiment-with-concurrenthashmap.html
總結(jié)
以上是生活随笔為你收集整理的试验ConcurrentHashmap的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux建库语句(linux建库)
- 下一篇: ddos接收时间报文大小不一致(ddos