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