使用并发hashmap来减少线程池的内存使用量?

时间:2011-08-31 14:51:36

标签: java memory-management hashmap threadpool concurrenthashmap

我正在使用一个运行冗长SQL查询的程序,并将处理后的结果存储在HashMap中。目前,为了解决每个20-200个查询的缓慢执行时间,我使用固定线程池和自定义可调用来进行搜索。因此,每个可调用对象都会创建数据的本地副本,然后将其返回到主程序以包含在报告中。

我注意到100个查询报告,过去没有问题,现在导致我的内存不足。我的推测是,因为这些callables正在创建自己的数据副本,所以当我将它们加入另一个大型HashMap时,我的内存使用量会增加一倍。我意识到我可以尝试通过尝试减少可调用表的范围来哄骗垃圾收集器运行,但是如果可以避免的话,那个重组级别并不是我想要做的。

我是否可以通过使用runnables替换callables而不是存储数据来改进内存使用,将其写入并发HashMap?或者听起来我在这里有其他问题?

3 个答案:

答案 0 :(得分:3)

不要创建数据副本,只需传递引用,确保线程安全(如果需要)。如果没有数据复制,您仍然有OOM,请考虑增加应用程序的最大可用堆。

不使用数据副本的上述方法的缺点是线程安全性更难以实现。

答案 1 :(得分:1)

您是否真的需要同时提供所有100-200份报告?

可能仅限50个报告限制第一级缓存,并根据WeakHashMap引入第二级? 当第一级超过其大小时,LRU将被推到第二级,这取决于可用内存量(使用 WeakHashMap )。

然后要搜索报告,首先需要查询第一级,如果值不存在查询第二级,如果值不存在那么当没有足够的内存而你必须再次查询数据库时,GC会回收报告对于这份报告。

答案 2 :(得分:0)

查询结果是否依赖于其他查询结果?如果没有,每当你在另一个线程中发现结果时,只需使用你所暗示的ConcurrentHashMap。你真的需要问一下,创建几个不必要的数据副本是否会导致程序内存不足?这应该是显而易见的。