【发布时间】:2010-11-13 13:14:58
【问题描述】:
最佳空闲堆与总堆的比率是多少?在这个比率的什么值下,我应该考虑增加堆大小/减小堆大小?
【问题讨论】:
标签: jvm size heap-memory
最佳空闲堆与总堆的比率是多少?在这个比率的什么值下,我应该考虑增加堆大小/减小堆大小?
【问题讨论】:
标签: jvm size heap-memory
理想的瞬时比率是 1。理想情况下,您的 JVM 将完全消耗它所需的内存,不多也不少。这是一个很难达到的目标;)
问题(正如 TNilsson 指出的那样)是您的应用程序的内存需求会随着时间的推移而变化,因此您希望它有足够的空间来避免导致持续收集/压缩的频率超出您的容忍范围,并且您希望它占用的空间很小,您不必购买更多 RAM。
【讨论】:
这可能取决于您分配新对象的速率。垃圾收集涉及大量来自活动对象的跟踪引用。我刚刚处理了一种情况,即有大量可用内存(例如使用了 500 MB,500 MB 可用),但是发生了如此多的数组分配,以至于 JVM 将花费 95% 的时间进行 GC。所以不要忘记运行时内存行为。
所有那些说“Java 中的对象分配非常快”之类的性能调优文章,却没有提到某些分配会导致 1 秒的 GC 时间,这让我发笑。
【讨论】:
没有一个简单的答案,让我举两个例子:
示例 1 - 您的程序在启动时分配了 100M 的内存,然后在接下来的运行中不再分配任何内存。
在这种情况下,您显然希望堆大小为 100M(嗯,也许是 101 之类的,但您明白了……)以避免浪费空间。
示例 2 - 您的程序每秒分配 10M 内存。没有任何数据的保留时间超过 1 秒。 (例如,您正在执行需要大量临时数据的计算,完成后将返回一个整数......)
知道确切的数字可能不太现实,但这是一个例子。
由于您有 10M 的“实时”数据,因此您必须至少有 10M 堆。除此之外,您需要检查垃圾收集器的工作方式。简而言之,一次 GC 完成所需的时间是 O(live set),即“死”数据量并没有真正进入其中。使用恒定的活动集大小,无论您的堆大小如何,您的 GC 时间都是恒定的。这会导致更大的堆 -> 更好的吞吐量。
(现在,要真正把事情搞砸,你添加诸如压缩堆之类的东西,图像变得更加不清晰......)
结论 这是问题的简化版本,但简短的回答是 - 视情况而定。
【讨论】: