簡體   English   中英

ConcurrentHashMap初始化

[英]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 :較高的負載系數值會減少空間開銷,但會增加查找成本。 這意味着它對getput有重大影響,因為這兩種方法都在內部進行查找。 默認情況下,它是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.

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