3

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

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

我可以通过将可调用对象替换为可运行对象而不是存储数据,而是将其写入并发 HashMap 来提高内存使用率吗?还是听起来我这里有其他问题?

4

3 回答 3

3

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

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

于 2011-08-31T14:56:28.763 回答
1

您真的同时需要所有 100-200 份报告吗?

将第一级缓存限制为 50 个报告并引入基于WeakHashMap的第二级缓存是否值得?当第一级超过其大小时,LRU 将被推送到第二级,这取决于可用内存的数量(使用Wea​​kHashMap)。

然后要搜索报告,您首先需要查询第一级,如果值不存在,则查询第二级,如果值不存在,那么当内存不足时,GC 会回收报告,您必须再次查询数据库以获取此报告.

于 2011-08-31T15:02:58.763 回答
0

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

于 2011-08-31T16:04:48.800 回答