StackOverflowError的JVM处理方式
2023-12-28 10:26:33
背景:
事情来源于生产的一个异常日志
Caused by: java.lang.StackOverflowError: null at java.util.stream.Collectors.lambda$groupingBy$45(Collectors.java:908) at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169) at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
发生该异常并定位到是某个规则的问题后,我们手动修复了规则,不过我们无法确定是否需要重启容器,所以引申出来了发生StackOverflowError是否需要重启容器恢复的讨论
JVM对StackOverflowError线程的处理
结论是JVM只会中断发生StackOverflowError的线程,对于其他未发生StackOverflowError的线程没有影响,验证代码如下:
package stackoverflow;
/**
* 验证JVM处理StackOverflowError的方式,只会中断异常线程,不影响主线程以及其他线程的执行
*/
public class StackOverFlowTest {
public static void main(String[] args) throws Exception {
Thread stackOverflowErrorThread = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(60000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 进入死循环
callRecursiveMethod();
}
}, "StackOverflowErrorThread");
Thread otherNormalThread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
System.out.println("I am otherNormalThread thread!!");
try {
Thread.sleep(10000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "otherNormalThread");
stackOverflowErrorThread.start();
otherNormalThread.start();
Thread.currentThread().setName("mainThread");
while (true) {
System.out.println("I am main thread!!");
try {
Thread.sleep(10000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 死循环模拟StackOverflowError
*/
public static void callRecursiveMethod() {
callRecursiveMethod();
}
}
未发生Stack Overflow之前
发生Stack Overflow之后
从输入日志也可以验证这一点:
参考:
https://blog.csdn.net/u011983531/article/details/79563162
文章来源:https://blog.csdn.net/lixia0417mul2/article/details/135257951
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!