私の目標は、ホットスポット 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