提问者:小点点

我应该设置MaxMetaspaceSize吗?


所以,问了这个问题后,很快就明白了,重要的问题不是“我怎么能”,而是“我应该”?

我们有客户正在从Java7迁移到Java8(使用Tomcat7)。Java7需要设置-XX: MaxPermSize,由于个人需求和使用,一些客户将其最大值提高到安装程序设置的默认值之上。

我应该为定义了自定义最大值的客户设置-XX: MaxMetaspaceSize(到之前的-XX:MaxPermSize设置)吗?新安装呢?我们应该设置-XX:MaxMetaspaceSize吗?

这样一个决定的利弊是什么?


共3个答案

匿名用户

正如我对上一个答案的评论,对这些内存池设置限制的原因是不同的。

如果您的用户以前将MaxPermSize增加到默认值以上,这可能是为了避免CMS的完全GC/并发模式故障,或者是因为他们的应用程序确实需要大量perm gen空间。

将metaspace限制从其有效的无限默认降低将服务于一个完全不同的目的:避免无界metaspace增长。

问题是这只是一个上限。实际提交的,即当前的metaspace大小会更小。事实上,有一个名为MaxMetaspaceFreeRatio的设置(默认70%),这意味着实际的metaspace大小永远不会超过其占用率的230%。

为了让它先增长,它必须填满,迫使垃圾回收机制(metaspace完整)试图释放对象,只有当它不能满足其MinMetaspaceFreeRatio(默认40%)目标时,它才会在GC周期后将当前metaspace扩展到不超过占用率的230%。

因此,在实践中,实际的metaspace大小应该稳定在与其实际需要接近的范围内,除非应用程序不断泄漏类加载器/类或生成大量动态代码。

太长别读:可能有限制metaspace尺寸的原因,但它们可能与设置烫发尺寸的原始原因不同。因此应该重新评估需求。

匿名用户

为了表达相反的观点,可以提出始终设置MaxMetaspaceSize的案例。将世界上的整个应用程序集分组为10个(二进制-想想吧)组可以讨论原因。不过,请记住,设置限制仅控制该空间的垃圾收集(GC)何时发生。

第01组:具有所有非动态类的应用程序

这个组将您放入上面提到的稳定区间。在这种情况下,要设置的大小相当容易确定(就像MaxPermSize一样),无论如何也不会有太多GC。

第10组:具有动态类的应用程序

鉴于高度强大的第三方库的激增,这个组中的几乎每个应用程序不是吗?通常你不关心库是不是Scala/Groovy/etc,它只是做你想要的事情,所以它被使用了。用一堆死的(动态)类填充Metaspace有什么价值?当GC真的到来时,它会很昂贵。我宁愿限制大小,使GC更频繁(但每个暂停时间更少),并且更容易在同一硬件上运行多个应用程序,而不必担心它们各自的元空间会相互冲突。

匿名用户

来自@eckes评论的回答:

我会设置一个足够大的最大值,在正常情况下不会触发。我这么说的原因是,如果本地内存耗尽或发生疯狂交换,系统可能会表现得非常不稳定且难以控制。比OOM或Java冻结要糟糕得多。例如使用2GB(感觉系统至少有2gb缓冲区空闲)