JVM 被杀死的场景?
Scenarios under which JVM gets killed?
我在想 JVM 可能因为编程错误而被杀死的所有场景?
有人声称 java.lang.OutOfMemoryError: Java heap space
不会导致 JVM
被杀死,但是当我 运行 我的程序断言时,发现这不是真的。我尝试了 this 程序
在哪里可以找到 recoverable
和 un-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...
我在想 JVM 可能因为编程错误而被杀死的所有场景?
有人声称 java.lang.OutOfMemoryError: Java heap space
不会导致 JVM
被杀死,但是当我 运行 我的程序断言时,发现这不是真的。我尝试了 this 程序
在哪里可以找到 recoverable
和 un-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...