一个线程OOM,进程里其他线程还能运行么?
引言
这题是某大厂面试的一个真题。大致如下:
一个进程有3个线程,如果一个线程抛出oom,其他两个线程还能运行么?
先说一下答案,答案是还能运行
不瞒大家说,真在面试中,我遇到这一题,我估计也是答错。因为我初看到这一题,内心嘿嘿一笑,觉得这题是在考察JVM的内存结构。我第一反应是OOM的常见情况 堆溢出,也就是下面的这种异常
java.lang.OutOfMemoryError: Java heap space
先回忆一下,多线程中栈与堆是公有的还是私有的?回答如下:
在多线程环境下,每个线程拥有一个栈和一个程序计数器。 栈和程序计数器用来保存线程的执行历史和线程的执行状态,是线程私有的资源。 其他的资源(比如堆、地址空间、全局变量)是由同一个进程内的多个线程共享。
也就是说,堆是线程共享。那么一个线程堆抛出OOM异常,我第一反应是另外两个线程也抛出OOM异常,毕竟堆是共有的,大家应该都抛出异常。于是,我决定写个代码去测试一下,结果我被 啪啪啪 打脸了。
测试代码伪如下:
一个线程去构造堆溢出,每隔1S申请一次堆,代码长下面这样:
new Thread(()->{ List<byte[]> list = new ArrayList<>(); //每个1秒申请1024 * 1024 * 1(1M)内存 while (true){ System.out.println(new Date().toString()+Thread.currentThread()+"=="); byte[] bytes = new byte[1024 * 1024 *1]; list.add(bytes); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } },"thread1").start();
另一个线程,睡眠1秒然后输出就好,代码长下面这样:
new Thread(() -> { while (true) { System.out.println(new Date().toString() + Thread.currentThread() + "=="); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }, "thread2").start();
结果,输出是长下面这样的:
大家发现了么,一个线程溢出了,其他线程还在跑,这好像和我们的认知不大一样。坦白说,我看到这个结果,瞬间觉得自己一世英名毁于一旦,从此无法抬起头来做人。没办法了,只能亮出工具来看一下了。
先说一下,在本例测试中,参数如下:
-Xms16m -Xmx32m -Xms 初始堆内存 -Xmx 最大堆内存
VisualVM 是一个性能分析工具,自从 JDK 6 Update 7 以后已经作为 Oracle JDK 的一部分,位于 JDK 根目录的 bin 文件夹下。
启动命令:
./bin/jvisualvm
作者:it_zzy
链接:https://www.jianshu.com/p/e26ef4429612
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦