我想使用 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
,您可以控制地图中最旧的条目何时被删除(当put
或putAll
被调用时)。
【讨论】:
然后您可以实现removeEldestEntry
以返回true
的size() > 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 脚本中同时使用多处理和多线程来加快执行速度
我同时装了两个处理器驱动(在不同的文件夹内)现在很卡,怎么办?