StackOverflowError的JVM处理方式

背景:

事情来源于生产的一个异常日志
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的线程没有影响,验证代码如下:

java 复制代码
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

相关推荐
zs宝来了9 小时前
AQS详解
java·开发语言·jvm
赵药师14 小时前
多进程-生产者消费者C++实现
java·开发语言·jvm
wgzrmlrm7415 小时前
SQL实现按用户偏好进行分组汇总_自定义聚合规则
jvm·数据库·python
Nyarlathotep011316 小时前
自动内存管理(2):垃圾收集器与内存分配策略
java·jvm·后端
xcjbqd016 小时前
CSS如何给Bootstrap侧边菜单加图标_使用font-awesome结合CSS
jvm·数据库·python
Java面试题总结17 小时前
2026年Java面试题最新整理,附白话答案
java·开发语言·jvm·笔记·spring·intellij-idea
light blue bird20 小时前
主从执行端动机模块工序协同组件
jvm·数据库·.net·桌面端
xcjbqd020 小时前
Python中Pandas如何将DataFrame写入MySQL_使用to_sql函数
jvm·数据库·python
呆呆在发呆.21 小时前
JavaEE初阶
java·jvm·网络协议·学习·udp·java-ee·tcp
xhuiting1 天前
JVM专题(一)
jvm