web-dev-qa-db-ja.com

Java 8メタスペースリークを診断するには?

いくつかの興味深い動作を備えたJ2EEアプリケーションがあります。ヒープは適切に動作するようで、ガベージコレクションによって時間の経過とともに予想どおりに拡大および縮小します。全体的に長期的なヒープの拡張は認められません。ただし、メタスペースは、MaxMetaspaceに到達してOOMEに遭遇するまで、1時間あたり約20 MBで着実に成長し続けます。パラレルガベージコレクタとG1ガベージコレクタ(jdk1.8.0_40)の両方を試しました。

アプリケーションは実行中に再デプロイされないため、典型的なクラスローダーリークのようには見えません。このリークの原因を追跡する方法についての提案はありますか?

34

ヒープダンプを行い、 Eclipse MAT で分析します。ロードしたクラスを見てください。予期しない何か、特に重複クラスがあるかどうかを確認します。また、クラスローダーエクスプローラーもあります。

編集:理論的には、常にプロキシを生成していることもあり得ます。

7

Java.lang.OutOfMemoryError:Metaspaceの主な原因は次のとおりです。

  • クラスが多すぎるまたは
  • 大きすぎるクラスがメタスペースにロードされています。

問題を再現するには、次のコードスニペットを使用します。

public class Metaspace {
static javassist.ClassPool cp = javassist.ClassPool.getDefault();

public static void main(String[] args) throws Exception {
    for (int i = 0; ; i++) { 
        Class c = cp.makeClass("eu.plumbr.demo.Generated" + i).toClass();
    }
  }
}

生成されたクラス定義はすべて、最終的にメタスペースを消費します。

Javaassist in Maven repo

OOMEの詳細については、こちらをご覧ください こちら

5
Karol Król