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

相关推荐
Tingjct5 小时前
线程详细讲解---聚焦linux
linux·服务器·jvm
myy-learn5 小时前
32 SQLITE数据库
jvm·数据库·sqlite
wuminyu8 小时前
JVM锁膨胀与Futex源码解析
java·linux·c语言·jvm·c++
郝学胜-神的一滴8 小时前
C++11 工程级应用 08:Lambda表达式与Tuple元组
开发语言·jvm·c++·python·程序人生·开源
袋鼠云数栈1 天前
整库迁移与分库分表同步:批量数据搬迁的配置简化思路
jvm·数据库·oracle
Mr. zhihao1 天前
JVM 偏向锁 4 秒延迟:从源码动机到 JEP-374 废弃全链路
jvm·并发·偏向锁
孙克旭_1 天前
JVM 入门详解:JVM、JRE、JDK 区别,JVM 基础结构梳理
java·开发语言·jvm
随遇而安zx1 天前
【地基篇】---JVM 内存结构知识点(Java 8 运行时数据区深度解析)
java·开发语言·jvm
恒拓高科WorkPlus1 天前
企业如何搭建安全内部通讯平台|企业内部通讯平台怎么选才更安全?
jvm·数据库·安全
随遇而安zx1 天前
【地基篇】---JVM 类加载 源码解析(基于 Java 8)
java·jvm·python