试验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的性能略慢。

结论

新的实现在内存测试中表现出色,并且在获取/输出测试中有点慢。 有几件事情可以做,以提高获取/输出的性能,我们看到的所有性能差异都归因于所使用的探测技术。

  • 可以改进探测技术,可以使用线性探测技术来获取缓存友好的访问。
  • 使探测技术并行化非常容易。

参考:Are Are ready博客上试验我们JCG合作伙伴 Ashkrit Sharma的ConcurrentHashmap

翻译自: https://www.javacodegeeks.com/2013/05/experiment-with-concurrenthashmap.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值