JVM被杀死的场景?

时间:2015-07-26 14:43:35

标签: java scala jvm

我正在考虑JVM因编程错误而被杀的所有场景?

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

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

由于

3 个答案:

答案 0 :(得分:5)

JVM将停止

  • 由于JVM中的错误导致崩溃时
  • 当所有非守护程序线程停止运行时
  • 调用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并没有停止,因为永无止境的线程继续运行。

答案 1 :(得分:3)

您似乎将不可恢复的误认为是 JVM退出的同义词。

实际上,OOME,ThreadDeath和SOE是不可恢复的,因为它们几乎可以在代码中的任何一点异步发生,包括JDK内部对象,并使它们保持不一致状态。

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

然后有JVM被杀死的外部原因。这再次与不可恢复的错误无关。

答案 2 :(得分:1)

  

我正在考虑JVM因编程错误而被杀的所有场景?

这取决于你被“杀死”的意思。

如果您错误地致电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...