banner
RustyNail

RustyNail

coder. 【blog】https://rustynail.me 【nostr】wss://ts.relays.world/ wss://relays.world/nostr

Javaのメモリブロック内のメモリオーバーフロー

Jvm の各パーティションの OOM を回避する方法を見つける

ヒープメモリ#

ヒープメモリのオーバーフローは、オブジェクトを継続的に作成し、GC によって回収されない(到達性分析、GC ルートとオブジェクトの間に到達可能なパスがある)場合に発生します。

パラメータ:-Xmx20m -Xms20m -XX:+HeapDumpOnOutOfMemoryError

byte[] a = new byte[21 * 1024 * 1024];

HeapDumpOnOutOfMemoryErrorを追加すると、ログをダンプして後続の OOM の問題を分析しやすくなります。

スタックメモリのオーバーフロー#

仮想マシンのスタックには、ローカル変数テーブルがあり、ローカル変数を継続的に作成することでオーバーフローさせることができます。

(ここでは OOM に成功しませんでしたが、それが Jvm の原因なのか何なのかわかりません)

パラメータ:-Xss1m -XX:+HeapDumpOnOutOfMemoryError

public void StackOOM() {
    while (true) {
        Thread thread = new Thread(this::job);
        thread.start();
    }
}

private void job() {
    while (true) {
    }
}

メソッド領域のオーバーフロー#

メソッド領域はクラスの情報を格納するために使用されるため、メソッド領域をオーバーフローさせるには、大量のクラスを動的に生成するだけです。クラスを生成するための比較的簡単な方法は、Cglib を使用することです。

Cglib を使用しているプロジェクトでは、メソッド領域のオーバーフローの例外が発生する可能性があります。たとえば、Spring の Aop では、多くの増強クラスが生成されると、多くのクラスが生成され、メソッド領域のサイズが不足すると例外が発生します。

-XX:PermSize=1M -XX:MaxPermSize=1Mを使用する場合は、jvm のバージョンが 8 未満であることを確認してください。なぜなら、Java1.8 では永久代が削除され、クラス情報が Meta Space に配置されるからです。

Meta Space の制御には、-XX:MetaspaceSize-XX:MaxMetaspaceSizeを使用します。

パラメータ:-XX=10m -XX=10m -Xmx20m -Xms10m

while (true){
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(TestMain.class);
    enhancer.setUseCache(false);
    enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> methodProxy.invokeSuper(o, objects));
    enhancer.create();
}

Exception in thread "main" java.lang.OutOfMemoryError: Metaspace

ダイレクトメモリのオーバーフロー#

ダイレクトメモリのオーバーフローは通常、Nio が発生する場所で発生します。たとえば、Netty です。unsafe メソッドを使用してシステムメモリを直接要求することで、ダイレクトメモリのオーバーフローをシミュレートできます。

パラメータ:-XX=10M -XX:+HeapDumpOnOutOfMemoryError

Field field = Unsafe.class.getDeclaredFields()[0];
field.setAccessible(true);
Unsafe unsafe = (Unsafe) field.get(null);
while (true) {
    unsafe.allocateMemory(1 * 1024 * 1024);
}

Exception in thread "main" java.lang.OutOfMemoryError
at sun.misc.Unsafe.allocateMemory(Native Method)

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。