动态分配缓存大小以减轻堆空间错误

时间:2010-09-28 14:23:47

标签: java memory memory-management allocation

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

是否有一种标准机制可以在运行时减小此缓存的大小以删除这些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; 

2 个答案:

答案 0 :(得分:0)

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

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

但是,如果你使用弱/软引用,你会得到OOME,我怀疑你的GC没有很好地调整。您的应用程序似乎遇到突然的内存消耗,导致OOME状况。这样的情况不太可能,但是可能,特别是如果之前的GC调用没有清除足够的内存(最终会被消费的下一次突然消耗)。

答案 1 :(得分:0)

为什么不使用设计为real cache的内容?

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