[英]ConcurrentHashMap Initialization
我們在ConcurrentHashMap
下面使用多線程應用程序中的Cache。
private static Map<String, TransactionPriceItemDetailSummaryVO> pritmSummaryMap = new ConcurrentHashMap<String, TransactionPriceItemDetailSummaryVO>();
我們正在創建130個正在訪問和更新此Map的線程 。
最終地圖的大小約為1億個(對象)。
我已經在線閱讀了我們需要為ConcurrentHasMap
指定參數以提高其性能的信息。
誰能建議我們如何為案例計算參數?
另外,最佳實踐是在此映射上調用clear()
釋放內存嗎?
從java doc出發: 理想情況下,您應該選擇一個值以容納與並發修改表一樣多的線程。 既然你說
... 130個正在訪問和更新此Map的線程
那你應該用
new ConcurrentHashMap<String, TransactionPriceItemDetailSummaryVO>(130)
就像@Bohemian所說的那樣,請設置一些更大的值以避免調整大小。 僅在不需要內容時才呼叫清除。
您可以使用以下構造函數配置Map:
ConcurrentHashMap<K,V>(initialCapacity, loadFactor, concurrencyLevel)
。
initialCapacity
:盡管您已經提到要插入100M對象,但是您是否要將它們保留在地圖中? 還是像添加和刪除對象? 如果要保留所有這些值而不是將其刪除, 110_000_000
將該值保留為110_000_000
建議的110_000_000
,否則,應在任何給定時間點將其保留為地圖的平均平均大小。
loadFactor
:較高的負載系數值會減少空間開銷,但會增加查找成本。 這意味着它對get
和put
有重大影響,因為這兩種方法都在內部進行查找。 默認情況下,它是0.75
,通常被認為是空間利用率和查找時間之間的良好折衷。
concurrencyLevel
:並發更新線程的估計數量。 在這種情況下,您提到的數字是130
通過在調用clear()
刪除所有元素時進行分析,可以進一步挖掘上述值。
地圖上有1億個物體!
IMO,在靜態映射中包含這么多的對象絕不是一個好主意。 另外,由於Map會占用大量內存,因此Java會占用大量內存。 您可能會在應用程序服務器中遇到頻繁的內存不足錯誤,並且轉儲每次都始終在其頂部始終放置java.util.Map(后跟無用的哈希碼)。
相信我,您不希望看到這樣的困難。 另外,當有130個線程正在訪問時,誰知道您的應用程序明天甚至可能擁有2億個對象,那么第二天就將有3億個對象! 始終牢記什么會導致此問題!
建議 :您可以繼續進行序列化(通過轉換為JSON?) TransactionPriceItemDetailSummaryVO
並將其保存在Redis中。 感覺到一些可擴展性? 簡單,將硬件添加到您的Redis服務器!
另外,Redis有許多到期政策(ttl,太好了!)
通過大量的條目和線程,您可以通過構造函數告訴它預期的大小,從而幫助實現更好的性能:
new ConcurrentHashMap<>(110_000_000, 10, 130);
嘗試不同的數字以找出有效的方法。
請注意,有了這么多項目,您將獲得較高的哈希沖突率。 考慮使用基於不同鍵的嵌套映射,以便每個映射具有較少的條目,例如1M以下。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.