0

私のアプリケーションでは、javassist ライブラリを使用して実行時に多くの Java クラスを作成しています。ある時点で ajava.lang.OutOfMemoryError: Metaspaceがスローされますが、Java プロセスの監視 (java.lang.management.MemoryPoolMXBean に基づく) は、十分な空きメタスペースがあることを報告します。何故ですか?また、メタスペースのメモリ プールを 100% 使用するにはどうすればよいでしょうか。

問題を再現する最小限のアプリケーションを作成しましたhttps://github.com/vlkv/java_metaspace_oom

それをダウンロードし、cd でプロジェクト ディレクトリに移動してから、'ant run' を実行します。このアプリでは、-XX:MaxMetaspaceSize=100m を設定しましたが、23564Kb 前後のメタスペースが使用されている時点で OOM がスローされます。

エラーのコール スタックは次のとおりです。

javassist.CannotCompileException: by java.lang.OutOfMemoryError: Metaspace
    at javassist.ClassPool.toClass(ClassPool.java:1170)
    at javassist.CtClass.toClass(CtClass.java:1316)
    at com.tradingview.Main.generateRandomClass(Main.java:53)
    at com.tradingview.Main.main(Main.java:24)
Caused by: java.lang.OutOfMemoryError: Metaspace
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:642)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at javassist.ClassPool.toClass2(ClassPool.java:1183)
    at javassist.ClassPool.toClass(ClassPool.java:1164)
    ... 3 more
4

1 に答える 1

0

うわー、私はちょうど答えを見つけました。問題は、私のアプリケーションでは、生成されたクラスごとに個別の新しい ClassLoader を作成することです。サンプル アプリで、生成されたすべてのクラスを 1 つの ClassLoader に配置する変更を行いました。その後、フリー メタスペースがほぼゼロになった時点で OOM がスローされます。修正はこちらhttps://github.com/vlkv/java_metaspace_oom/commit/d6bcade51f79758e2413d1852c771f163392c294ブランチ fix_of_the_problem

Javaプロセスでのクラスローダーの制限について知っている人はいますか? そして、それらを増やす方法は?

また、これはなぜ MetaSpace Size が Used MetaSpace の 2 倍の大きさなのかを見つけました。

于 2016-12-07T08:51:15.623 に答える