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

相关推荐
earthzhang20213 小时前
第3讲:Go垃圾回收机制与性能优化
开发语言·jvm·数据结构·后端·性能优化·golang
零千叶8 小时前
【面试】Java JVM 调优面试手册
java·开发语言·jvm
黄昏晓x9 小时前
C++----多态
java·jvm·c++
linweidong15 小时前
理想汽车Java后台开发面试题及参考答案(下)
jvm·spring boot·spring cloud·rpc·虚拟机·feign·二叉树排序
大大大大物~15 小时前
JVM之锁优化(自旋锁 适应性自旋 锁消除 锁粗化 轻量级锁 偏向锁)
jvm
无毁的湖光Al19 小时前
日常问题排查-Younggc突然变长
java·jvm·后端
..Cherry..20 小时前
【java】jvm
java·开发语言·jvm
zz-zjx1 天前
JVM 内存结构与 GC 机制详解( 实战优化版)
java·jvm·tomcat
siriuuus1 天前
JVM 内存分区及 GC 垃圾回收 相关知识总结
jvm·full gc
Arlene1 天前
JVM Java虚拟机
java·开发语言·jvm