それで、 this の質問をした後、重要な質問は「どうすればいいのか」ではなく、「すべきか」であることがすぐに明らかになりました。
(Tomcat7を使用して)Java7からJava8に移行するお客様がいます。 Java7は-XX:MaxPermSize
、を設定する必要があり、一部のお客様は、個々のニーズと使用のために、インストーラーによって設定されたデフォルトを超えて最大値を増やしました。
Iは、カスタム最大値を定義した顧客の-XX:MaxMetaspaceSize
を(前の-XX:MaxPermSize
設定に)設定する必要がありますか?新規インストールについてはどうですか? -XX:MaxMetaspaceSize
を設定する必要がありますか?
そのような決定の長所と短所は何ですか?
前の回答でコメントしたように、これらのメモリプールに制限を設定するためのreasonsは異なります。
ユーザーが以前に増加 MaxPermSizeをデフォルトより上にした場合、おそらくCMSでのフルGC /同時モード障害を回避するためか、アプリケーションが大量のperm genスペースを本当に必要としていたためです。
メタスペースの制限を実質的に無限のデフォルトから減らすことは、無制限のメタスペースの成長を回避するというまったく異なる目的に役立ちます。
問題は、それが単なる上限であることです。実際にコミットされる、つまりcurrentメタスペースのサイズは小さくなります。実際、MaxMetaspaceFreeRatio
(デフォルトは70%)という設定があります。これは、実際のメタスペースのサイズが占有率の230%を超えないことを意味します。
そして、最初にそれを成長させるには、オブジェクトを解放しようとしてガベージコレクション(メタスペースがいっぱい)を強制し、MinMetaspaceFreeRatio
(デフォルト40%)の目標を達成できない場合にのみ展開しますcurrent GCサイクル後の占有率の230%以下のメタスペース。
そのため、実際には、アプリケーションがクラスローダー/クラスを継続的にリークしているか、大量の動的コードを生成していない限り、実際のメタスペースサイズは実際のニーズに近い帯域内で安定するはずです。
TL; DR:メタスペースサイズを制限する理由があるかもしれませんが、perm genサイズを設定する元の理由とは異なる可能性があります。したがって、必要性を再評価する必要があります。
反対意見を放映するために、MaxMetaspaceSizeを常に設定するケースを作成できます。世界のアプリケーションセット全体を10個の(バイナリ-考えてみてください)グループにグループ化すると、その理由を議論できます。ただし、制限を設定するのは、そのスペースのガベージコレクション(GC)がいつ発生するかを制御するだけです。
グループ01:すべての非動的クラスを持つアプリケーション
このグループは、上記の安定したバンドにあなたを置きます。この場合、設定するサイズは(MaxPermSizeがそうであったように)決定するのがかなり簡単であり、とにかく多くのGCはありません。
グループ10:動的クラスを持つアプリケーション
非常に強力なサードパーティライブラリの急増を考えると、とにかくこのグループのほとんどすべてのアプリケーションではありませんか?多くの場合、ライブラリがScala/Groovy/etcであるかどうかは気にせず、必要なことを正確に行うため、使用されます。メタスペースをデッド(動的)クラスのごみで埋めることの価値は何ですか? GCが来ると、高価になります。サイズを制限し、GCをより頻繁に(ただし、それぞれの一時停止時間を短縮して)、個々のメタスペースが互いに実行されることを心配せずに、同じハードウェアで複数のアプリケーションをより簡単に実行します。
@ eckesコメントからの回答:
私は、通常の状況でトリガーしないように十分に大きい最大値を設定します。私がこれを言う理由は、ネイティブメモリが使い果たされたり、ワイルドスワッピングが発生した場合、システムは非常に不安定で制御が困難になる可能性があるためです。 OOMまたはJavaフリーズ。たとえば、2GBを使用する(最低でも2GBのバッファを解放するようにシステムを選択する)よりも悪い。