我正在考虑JVM因编程错误而被杀的所有场景?
SomeOne声称java.lang.OutOfMemoryError: Java heap space
不会导致JVM
被杀,但是当我运行我的程序断言时,这并不是真的。我尝试了this程序
我在哪里可以找到recoverable
和un-receoverable
错误的列表?
由于
答案 0 :(得分:5)
JVM将停止
抛出异常或错误永远不会停止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...