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

相关推荐
程序员二叉1 小时前
【JUC】线程池全套深度详解|参数|流程|拒绝策略|调优|异常处理
java·开发语言·jvm·算法·面试·juc
小马爱打代码6 小时前
面试题:内存模型与垃圾回收深度解析
jvm
cfm_29149 小时前
JVM底层源码深度解析:读写屏障(Read/Write Barrier)
jvm
wuminyu10 小时前
Java世界中StringTable源码剖析
java·linux·c语言·jvm·c++
醉颜凉11 小时前
Elasticsearch性能优化:JVM GC调优全攻略,彻底解决集群卡顿、吞吐量下降问题
jvm·elasticsearch·性能优化
顺风尿一寸12 小时前
从 Java 到内核:探秘线程改名的完整路径
jvm
lihao lihao14 小时前
linux线程
java·开发语言·jvm
南极企鹅1 天前
JVM-编译执行过程
jvm
苏克贝塔1 天前
.NET开发之.net framework对比.net core
jvm
cfm_29141 天前
JVM垃圾收集算法与收集器深度解析
jvm·测试工具·算法·性能优化