4

我的目标是在抛出 java.lang.OutOfMemoryError 时执行脚本(Windows 批处理文件),按照Hotspot VM Options中描述的选项

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

当抛出 OutOfMemoryError 时,我无法执行脚本或任何其他进程。首先我尝试启动 cmd.exe 并指定脚本的路径,我修改了双引号的位置,使用前斜杠而不是反斜杠,使用双反斜杠。我完全放弃了斜杠和引号,并在工作目录或 PATH 上尝试了简单的 .exe。没有任何效果。

我什至无法尝试运行任何可执行文件。通过使用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。有关触发 OOME 处理程序的 Perception 的 OutOfMem 类,请参见下文。整理好之后,语法就很简单了,引号可以包围整个选项,也可以只是等号后面的部分。对于 Windows shell 脚本,可以使用:

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 回答