java 工作线程内存溢出(OOM)!进程内的其他线程还会继续工作吗?

Java 工作线程OOM,会怎么样?

初看到这一问题,觉得这题是在考察JVM的内存结构。我第一反应是OOM的常见情况堆溢出,也就是下面的这种异常

java.lang.OutOfMemoryError: Java heap space

默想如下

在多线程环境下,每个线程拥有一个栈和一个程序计数器。栈和程序计数器用来保存线程的执行历史和线程的执行状态,是线程私有的资源。其他的资源(比如堆、地址空间、全局变量)是由同一个进程内的多个线程共享。

所以按照这个思路去思考的话,看到这个题目首先就会想到 如果堆内存是共享的话,那么单独的子线程内存溢出也就是堆占用满了 其他线程自然也就不能工作了。然后实验结果却不是这样

开始实验

编译工具:IDEA
电脑系统: Mac
内存检测工具:VisualVm

基本参数设置如下:

-mx80 -XX:MaxPermSize=50m
最大可用的堆内存是80M 最大可使用的非堆内存是50m按需分配

测试参数设置

测试代码如下

        public static void main(String[] args) {

        long memory = Runtime.getRuntime().maxMemory();
        System.out.println(String.format("%d (%.2f M)", memory, (double) memory / (1024 * 1024)));

        Thread mThreadTest = new Thread(() -> {
            List<byte[]> list = new ArrayList<byte[]>();
            while (true) {
                System.out.println(new Date().toString() + Thread.currentThread() + "==");
                byte[] b = new byte[1024 * 10240 * 1];
                list.add(b);
                try {
                    Thread.sleep(3000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        mThreadTest.start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                    }
                    System.out.println("test");
                }

            }
        }).start();
    }

}

代码应该比较容易看懂,开了两个工作线程一个,第一个线程每隔3秒分配1m的内存空间,第二个每隔一秒输出一个test

在这里插入图片描述

注意看9:43:00 前后,内存到达一个峰值以后立刻就降下来了。并且打印出OutOfMemoryError,打印test的线程仍在继续运行
在这里插入图片描述
结论

当一个线程抛出OOM异常后,它所占据的内存资源会全部被释放掉,从而不会影响其他线程的运行!

猜你喜欢

转载自blog.csdn.net/zhujohnle/article/details/90201051