【问题标题】:Dynamically Allocate Cache Size to Alleviate HeapSpace Error动态分配缓存大小以减轻 HeapSpace 错误
【发布时间】:2010-09-28 14:23:47
【问题描述】:

我们有一个对象集合,随着时间的推移会变得非常大。我们已经实施了缓存策略来帮助缓解这种情况,但是如果在启动时没有分配足够的内存,我们仍然会在运行时耗尽堆空间。

是否有一种标准机制可以在运行时减小此缓存的大小以消除这些 OutOFMemory 错误?这样,如果我们的进程以比正常情况更小的内存片启动,我们有望避免服务器死机。

我意识到这是一种错误类型,因此不应被捕获/处理,因为它通常表示更严重的问题。

是不是就这么简单:

private static final long RECOMMENDED_MEMORY = 1073741824L;  //Example 1 Gig
private static int recommendedCacheSize = 100; //Example of 100 items
long heapSize = Runtime.getRuntime().totalMemory();
double size = Math.floor((double) heapSize/RECOMMENDED_MEMORY * recommendedCacheSize);
recommendedCacheSize = ++size; 

【问题讨论】:

  • 注意:这是在Tomcat中运行的。
  • 缓存是使用软引用还是弱引用构建的?

标签: java memory memory-management allocation


【解决方案1】:

为什么不使用设计为real cache 的东西?

虽然您可以使用软引用来实现对内存敏感的缓存,但此类缓存往往会使对象在内存中停留的时间过长(增加您的 GC 负载)。弱引用不适合缓存,因为它们被清除的可能性要高得多(实际上,它们在每次 GC 时都会被清除)。

【讨论】:

    【解决方案2】:

    我怀疑缓存实现不维护 WeakReferenceSoftReference 对象的缓存,这些对象通常用于 Java 对象缓存。对缓存使用软引用或弱引用非常重要,否则可能会引发 OOME(内存不足错误)。

    使用软/弱引用的理由是垃圾收集器会尝试收集这些对象,以防没有足够的内存可用。使用强引用(普通对象引用)将对象引用存储在缓存中,会阻止内存被回收。

    但是,如果您在使用弱/软引用的情况下仍获得 OOME,我怀疑您的 GC 没有很好地调整。您的应用程序似乎突然出现内存消耗激增,从而导致 OOME 情况。这种情况不太可能发生,但可能发生,特别是如果之前的 GC 调用没有清除足够的内存(最终会被下一次消耗量消耗掉)。

    【讨论】:

    • 我们的对象缓存正在使用 Apache Commons KeyedObjectPool,所以我们应该满足这个标准。我相信我们的默认设置太高的真正问题。这个想法是允许每个开发者根据他们机器的能力有不同的缓存大小。
    • @Scott,除非您使用 Commons Pool 中的 SoftReferenceObjectPool,否则您不会在下面使用软引用。此外,Commons Pool 是一种池化实现,而不是缓存。它有自己的驱逐算法,这显然与 GC 不同。因此,您可能需要检查是否正在发生任何对象驱逐 - 没有任何驱逐将解释 OOME。
    • 如果我们将 maxIdle 设置为 1 并将 whenExhaustedAction 设置为 BLOCK,这不应该用作缓存吗?我们正在使用 GenericKeyedObjectPool
    • @Scott,这有点难说。我只看了一下池是如何在内部实现的,并没有详细检查 evictor。出于好奇,您如何指定您提到的这些值?
    • 我们是 commons pool 1.2,所以我们在这个对象的默认构造函数中使用以下调用——注意大小的设置是在实例化 GenericKeyedObjectPool 之后完成的: GenericKeyedObjectPool pool = new GenericKeyedObjectPool(this); pool.setMaxIdle(1); pool.setWhenExhaustedAction(GenericKeyedObjectPool.WHEN_EXHAUSTED_BLOCK);
    猜你喜欢
    • 2016-05-14
    • 2020-11-23
    • 2019-06-15
    • 2019-04-26
    • 1970-01-01
    • 1970-01-01
    • 2014-09-29
    相关资源
    最近更新 更多