[英]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.