4

私の目標は、ホットスポット VM オプションで説明されているオプションに従って、java.lang.OutOfMemoryError がスローされたときにスクリプト (Windows バッチ ファイル) を実行することです。

-XX:OnOutOfMemoryError="<cmd args>; <cmd args>"

OutOfMemoryError がスローされたときに実行するスクリプトやその他のプロセスを取得できません。まず、cmd.exe を起動してスクリプトへのパスを指定し、二重引用符の場所を変更し、バックスラッシュの代わりにフロントスラッシュを使用し、二重バックスラッシュを使用しました。スラッシュと引用符を完全に放棄し、単純な .exe を作業ディレクトリまたは PATH でライブで試しました。何も機能しません。

実行可能ファイルを実行しようとしても取得できません。ProcMonを使用することで、JVM は指定した名前の実行可能ファイルを探しておらず、ましてや起動しようとしていないことがわかりました。

意図的にタイプミスを挿入するとエラーが発生するため、JVM パラメータでオプションが正しく指定されていることはわかっています。私は次のようなことを試みています:

java -XX:OnOutOfMemoryError=myprocess.exe com.mycompany.SimulateOome
java -XX:OnOutOfMemoryError="myprocess.exe" com.mycompany.SimulateOome
java "-XX:OnOutOfMemoryError=myprocess.exe" com.mycompany.SimulateOome

これにより、予想されるスタック トレースが stdout/err に生成されます。

それは私のテストクラスかもしれません。私の現在のバージョンは単に java.lang.OutOfMemoryError をスローします。また、大きな配列を割り当てることで、より有機的な OOME をシミュレートしました。どちらも機能しません。

Windows 2003/2008 で JDK 1.6.0_38 を使用していますが、JDK 1.7 も試しました。

編集:

テストクラスに問題がありました。単純に例外をスローしたり、単純に巨大な配列を割り当てたりしても、OOME ハンドラーが起動することはありません。OOME ハンドラーをトリガーする Perception の OutOfMem クラスについては、以下を参照してください。それを整理すると、構文は簡単になり、引用符はオプション全体を囲むことも、等号の後の部分だけを囲むこともできます。Windows シェル スクリプトの場合は、次を使用できます。

java "-XX:OnOutOfMemoryError=c:\windows\system32\cmd.exe /c c:\scripts\my_oome_handler.bat" com.mycompany.MyClass

また

java -XX:OnOutOfMemoryError="c:\windows\system32\cmd.exe /c c:\scripts\my_oome_handler.bat" com.mycompany.MyClass
4

2 に答える 2

6

それは私のテストクラスかもしれません。私の現在のバージョンは単に java.lang.OutOfMemoryError をスローします。また、より有機的な OOME をシミュレートしましたが、大きな配列を割り当てました。どちらも機能しません。

私はこれをテストしましたが、実際にそうであるようです。理由についてはまだしっかりとした説明を探していますが、Java 7 を使用しています。

public class OutOfMem {
    public static void main(final String[] args) {
        final List<byte[]> segments = new ArrayList<byte[]>(64000);

        final int size = 6400000;

        for (int i = 0; i < 1000000000; i++) {
            segments.add(new byte[size * i]);
        }

        for (final byte[] data : segments) {
            final int dataSize = data.length;
            System.out.printf("Segment [size=%s]\n", dataSize);
        }
    }
}

上記でjava "-XX:OnOutOfMemoryError=ls" OutOfMem実行すると問題なく動作します (ls コマンドを実行します)。ただし、このクラスでは:

public class OutOfMem2 {
        public static void main(final String[] args) throws Throwable {
                throw new OutOfMemoryError("Fake OOME");
        }
}

実行java "-XX:OnOutOfMemoryError=ls" OutOfMem2すると例外スタックトレースが吐き出されますが、実際には OOME ハンドラーは起動されません。

于 2013-01-28T21:57:56.047 に答える
1

引数を引用符で囲んでみましたか?

java -XX:OnOutOfMemoryError="myprocess.exe SimulateOome"

また、 myprocess.exe が PATH を介してアクセスできることを確認するか、代わりにプロセスへの完全なパスを指定してください。

于 2013-01-28T21:21:12.957 に答える