メソッド領域オーバーフロー
2173 ワード
メソッドはクラス名、アクセス修飾子、定数プール、文字記述、メソッド記述など、Classに関する情報を格納するために使用されます.この領域のテストでは,実行時に大量のクラスを生成してメソッド領域を埋め尽くし,オーバーフローを知ることが基本構想である.Java SE APIを直接使用してクラス(反射時のGeneratedConstructorAccessorや動的エージェントなど)を動的に生成することも可能であるが,今回の試験でCGLIBを用いてバイトコードの実行を直接操作した場合,大量の動的クラスが生成される.
注目すべきは、Spring、Hibernateがクラスを強化する場合、CGLIBのようなバイトコード技術が使用されることです.強化されたクラスが多ければ多いほど、動的に生成されたClassがメモリのようにロードされることを保証するために、大きなメソッド領域が必要になります.例:
Caused by: java.lang.OutOfMemoryError:PermGen space
JDK 1.764ビット運転結果は以下の通り.
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
Exception in thread "main"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"
メソッド領域オーバーフローも一般的なメモリオーバーフロー異常であり,1つのクラスがゴミ回収器で回収される場合,判定条件が非常に厳しく,頻繁に大量のClassを動的に生成するアプリケーションでは,クラスの回収状況に特に注意する必要がある.このようなシナリオでは,前述したプログラムでGCLIBバイトコードを用いた拡張に加えて,JSPやJSPファイルを動的に生成するアプリケーション(JSPの最初の実行時にJAVAクラスにコンパイルする必要がある),OSGIベースのアプリケーション(同じクラスファイルであっても異なるローダでロードされても異なるクラスとみなされる)などが一般的である.
#JVMパラメータを追加してClass loadをすばやく位置決めし、位置決めします.
-XX:+TraceClassLoading-XX:+TraceClassUnloading出力形式:[Loaded sun.rmi.server.LoaderHandler from/usr/local/java/jdk 1.7.0/jre/lib/rt.jar]追加したCLASSファイルソースを簡単に見つけることができます
注目すべきは、Spring、Hibernateがクラスを強化する場合、CGLIBのようなバイトコード技術が使用されることです.強化されたクラスが多ければ多いほど、動的に生成されたClassがメモリのようにロードされることを保証するために、大きなメソッド領域が必要になります.例:
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
* VM args -XX:PermSize=10M -XX:MaxPermSize=10M
*
*/
public class JavaMethodAreaOOM {
public static void main(String[] args) {
while (true) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(OOM.class);
enhancer.setUseCache(false);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method arg1, Object[] args, MethodProxy proxy) throws Throwable {
return proxy.invokeSuper(obj, args);
}
});
OOM oom = (OOM) enhancer.create();
oom.sayHello("Kevin LUAN");
}
}
static class OOM {
public String sayHello(String str) {
return "HI " + str;
}
}
}
Caused by: java.lang.OutOfMemoryError:PermGen space
JDK 1.764ビット運転結果は以下の通り.
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
Exception in thread "main"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"
メソッド領域オーバーフローも一般的なメモリオーバーフロー異常であり,1つのクラスがゴミ回収器で回収される場合,判定条件が非常に厳しく,頻繁に大量のClassを動的に生成するアプリケーションでは,クラスの回収状況に特に注意する必要がある.このようなシナリオでは,前述したプログラムでGCLIBバイトコードを用いた拡張に加えて,JSPやJSPファイルを動的に生成するアプリケーション(JSPの最初の実行時にJAVAクラスにコンパイルする必要がある),OSGIベースのアプリケーション(同じクラスファイルであっても異なるローダでロードされても異なるクラスとみなされる)などが一般的である.
#JVMパラメータを追加してClass loadをすばやく位置決めし、位置決めします.
-XX:+TraceClassLoading-XX:+TraceClassUnloading出力形式:[Loaded sun.rmi.server.LoaderHandler from/usr/local/java/jdk 1.7.0/jre/lib/rt.jar]追加したCLASSファイルソースを簡単に見つけることができます