【问题标题】:ConcurrentHashMap memory management or alternative?ConcurrentHashMap 内存管理还是替代方案?
【发布时间】:2014-02-24 21:28:41
【问题描述】:

ConcurrentHashMapjava-websocket WebSocketClients 作为值的内存在不断增长。

我已将其隔离到每秒尝试重新连接到对等白名单的代码部分。我已经测试过在连接失败后是否正确删除了条目,并且确实如此。我还查看了所有可以找到的“concurrenthashmap memory leak”。

我不知道如何实现this possible solution。该解决方案是否解决了问题?如果有,请提供示例代码。

我尝试实现this suggestion

ConcurrentHashMap<String, MyClass> m =
  new ConcurrentHashMap<String, MyClass>(8, 0.9f, 1);

我认为这在一定程度上减缓了增长率,但我不知道如何调整它。这通常是正确的方法吗?如果有,请提供示例代码。

我还尝试按照此处的建议切换到HashTable,但我立即得到ConcurrentModificationExceptions,所以我认为这已经过时了。

当每秒快速插入和删除数千个条目时,如何管理 ConcurrentHashMap 实现的内存?如果不能,是否有替代方案?


通过引用而不是复制传递

我添加了一个HashMap,它存储了一个newWebSocket,并且只有当它和ConcurrentHashMap 一样不存在时才能重新尝试连接。

这极大地改进了内存管理,但它仍然会泄漏一点点,大约每 5 秒泄漏 0.1 MB,大约每秒尝试 5 次。

这是我的代码、WebSocket 的“析构函数”或ConcurrentHashMap 对已删除值的管理的问题吗?


死了Objects?

增长速度再次大大降低,因为我从ConcurrentHashMap 调用close() 之前在WebSocketClient 上调用remove(),最后从HashMap 调用remove()

WebSocketClient 在被关闭并从两个地图中删除后如何以及为什么仍然存在?


System.gc();

泄漏率再次大幅降低!

我在remove()之后调用它。

【问题讨论】:

  • 几个问题: 1.) 您使用的是哪个 VJM 运行时? 2.) 你如何测试对象的大小? 3.) ConcurrentHashMap 是否引用了任何“死”对象?使用堆分析工具来解决这个问题stackoverflow.com/questions/2064427/… 用于堆分析工具。问候 也许这可以帮助您确定
  • @Tinman 非常感谢 Tinman! 1) 最新的或第一个到最新的 Java SDK,Linux 上的 JRE,直接来自 Oracle。 2)CHM.size() 始终报告0。 3)我怎么会知道呢? (我=菜鸟)。我一定会研究堆分析!再次非常非常非常非常感谢您!
  • 好的,所以当我问你如何测试大小时,我的意思是该对象在内存中的大小。 “移除”的 Socked Connect 将保留在堆中,直到垃圾收集器 (GC) 将它们移除。 GC 只会时不时地这样做。
  • @Tinman 再次非常感谢 Tinman!我仍然不知道该怎么做。我正在使用 VisualVM,但我不知道要寻找什么。堆转储中有大量的char[]s 和Strings。手动调用System.gc() 减慢了速度,但仍有速度。我现在用的是VisualVM,当我点击“Perform GC”时,它大大减少了正在使用的内存量。它是否使用“特殊”GC?再次非常感谢您!
  • 您是否已经了解此博客中的所有内容? javarevisited.blogspot.com.au/2011/04/…

标签: java concurrenthashmap java-websocket


【解决方案1】:

地图本身泄漏的可能性很小。可能发生的情况是,如果它与地图有关,那么当您完成地图时,您无法从地图中删除数据。只要地图指向它,它就无法获得 GC。

【讨论】:

  • 谢谢凯什拉姆!我remove() 并检查size(),它始终在0 附近报告。即使 WebSocketClient 已从地图中删除,它是否仍然存在?提前非常感谢您!
  • @MichaelT 非常感谢 MichaelT!堆转储显示很多char[]s 和Strings。当我使用它的“Perform GC”时,使用中的内存急剧下降。是不是在使用System.gc() 以外的东西?非常非常感谢您!
  • 如果 GC 正在清理它,这不是泄漏。请记住,GC 会消耗周期,因此 JVM 通常会尝试推迟垃圾收集,直到它们使用了大量内存并需要恢复它。
猜你喜欢
  • 1970-01-01
  • 2011-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多