我想使用 java 集合来加快处理速度但同时避免内存堆异常?

Posted

技术标签:

【中文标题】我想使用 java 集合来加快处理速度但同时避免内存堆异常?【英文标题】:I want to use a java collection in order to speed up processing but at same time avoid memory heap exceptions? 【发布时间】:2012-08-10 18:10:29 【问题描述】:

我想使用一个 java 集合(列表、地图等)来缓存一些数据,这样我就可以使用这个缓存而不是直接检查数据库。我唯一担心的是集合大小,我希望这个缓存可以保存假设只有 1000 个条目,一旦达到这个计数,我想删除最旧的条目并放置一个新条目。这可能吗?

【问题讨论】:

是的,但这将如何加快处理速度? 我没有查询数据库来获取对象的 id,而是先查看地图,看看我之前是否在数据库中搜索过相同的项目。 如果是少量条目(如少于 10,000 个),您不会想要进行不必要的优化。数据库可以很快地为您获取结果,而无需缓冲它们,因此会占用更多内存。 @Makoto 也许是一个超低延迟的金融应用。然后数据库查找是不行的。但我们不知道... 您可能想阅读以下内容:Soft reference LinkedHashMap in Java? 【参考方案1】:

根据每个缓存对象的“权重”,有多种变体。选择更适合您的用例:

固定大小的缓存(可以使用集合实现并跟踪其大小)。如果对象相当小并且可以提前很好地估计内存占用,则此方法效果很好。其他答案基本上说明了实现这种类型的方法。

通过垃圾收集器自动驱逐的动态缓存。如果要缓存的对象很大(或大小变化很大,例如文件或图像)并且您希望使用尽可能多的堆可用于缓存,则此方法效果很好。缓存管理 java.lang.SoftReference 的集合以使对象保持活动状态。 当它需要内存时,垃圾收集器将回收缓存的对象(通过清除引用)。这种方法的一个缺点是您无法控制对象驱逐,GC 决定何时以及哪些对象被驱逐。

两者结合,(小)固定大小缓存用于最近命中,动态 GC 用于二级缓存。

如果配置得当,都不会导致任何 OutOfMemory 错误。

【讨论】:

以下是关于该主题的讨论:Soft reference LinkedHashMap in Java?【参考方案2】:

Apache commons 有一个circular fifo buffer。我想这就是你要找的。

来自其文档

CircularFifoBuffer is a first in first out buffer with a fixed size that replaces its oldest element if full.

否则

您可以在 java 库中创建自己的扩展 AbstractQueue 的类。

【讨论】:

【参考方案3】:

你应该看看LinkedHashMap。如果您覆盖removeEldestEntry,您可以控制地图中最旧的条目何时被删除(当putputAll 被调用时)。

【讨论】:

然后您可以实现removeEldestEntry 以返回truesize() > 1000。 JavaDoc 中有一个这样的例子。【参考方案4】:

Java 提供了一个名为Queue 的接口,以及该接口的一些实现。

您可以看到解决问题的最佳选择。看看

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Queue.html

http://docs.oracle.com/javase/tutorial/collections/implementations/queue.html

【讨论】:

【参考方案5】:

您可以使用 Google Guava 提供的缓存实用程序:http://code.google.com/p/guava-libraries/wiki/CachesExplained

【讨论】:

以上是关于我想使用 java 集合来加快处理速度但同时避免内存堆异常?的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 脚本中同时使用多处理和多线程来加快执行速度

我同时装了两个处理器驱动(在不同的文件夹内)现在很卡,怎么办?

自建DNS缓存服务器加快上网速度

java用啥方法插入数据量很大但速度又快。

c# for循环效率问题,遍历list<string>集合;

带有排序的 MongoDB 范围查询 - 如何加快速度?