JVM 被杀死的场景?

Scenarios under which JVM gets killed?

我在想 JVM 可能因为编程错误而被杀死的所有场景?

有人声称 java.lang.OutOfMemoryError: Java heap space 不会导致 JVM 被杀死,但是当我 运行 我的程序断言时,发现这不是真的。我尝试了 this 程序

在哪里可以找到 recoverableun-receoverable 错误的列表?

谢谢

JVM 将停止

  • 当它由于 JVM 中的错误而崩溃时
  • 当所有非守护线程停止时 运行ning
  • 调用 System.exit()

抛出异常或错误永远不会停止 JVM。但是,如果它没有被捕获,它可以做什么,如果导致调用它的线程终止其执行。如果它是 运行 的最后一个非守护线程,那么 JVM 将停止。

示例:

public static void main(String[] args) {
    Runnable r = new Runnable() {
        public void run() {
            while (true) {
                System.out.println("still running...");
                try {
                    Thread.sleep(1000L);
                }
                catch (InterruptedException e) {
                    // ignore: I don't want to die
                }
            }
        }
    };

    Thread neverEndingThread = new Thread(r);
    neverEndingThread.start();

    List<byte[]> arrays = new ArrayList<>();
    for (int i = 0; i < 1000; i++) {
        byte[] hugeArray = new byte[2_000_000_000];
        arrays.add(hugeArray);
    }
    System.out.println(arrays);
}

执行这段代码会启动一个新线程,然后会导致主线程抛出OutOfMemoryError。由于此错误未被主线程捕获,因此主线程停止执行。但是 JVM 不会停止,因为永无止境的线程会继续 运行.

您似乎将 不可恢复 误认为是 JVM 退出

在实践中,OOME、ThreadDeath 和 SOE 是不可恢复的,因为它们几乎可以在代码中的任何位置异步发生,包括 JDK- 内部对象并使它们处于不一致状态。

这可能会导致各种未定义的行为,但这并不一定意味着 JVM 退出。活锁、死锁或根本不正确的结果也是可能的。

再就是JVM被kill的外部原因。同样,这与不可恢复的错误无关。

I am thinking of all the scenarios where JVM could get killed because of Programming Errors?

这取决于你"killed"的意思。

如果您调用 System.exit(0); 不正确,这将退出程序。

此外,如果您不正确地使用 Unsafe 或在本机代码中触发信号,这也会导致程序退出。

虽然 Error 可能被认为是不可恢复的,但这并不会停止进程,即使这可能是可取的。您可以捕获此类错误并在退出前记录它。

try {
    many operations

} catch(Error e) {
    // log the error

    // force the program to shutdown
    System.exit(-1);
}

注意:如果您放弃错误,线程将保留 运行,如果一个线程死亡,它不会杀死其余线程,除非它们都是守护线程。

另请注意:您可以像这样很容易地生成 OutOfMemoryError

try {
   throw new OutOfMemoryError("Just because...");

} catch (Error e) {
   // pretend it didn't happen.
}
// thread continues...