• 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html
  • 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html

美团三面:一个线程OOM,进程里其他线程还能运行么?

技术杂谈 勤劳的小蚂蚁 2个月前 (02-05) 69次浏览 已收录 0个评论 扫描二维码

这题是一个网友 @大脸猫爱吃鱼给我的提问,出自今年校招美团三面的一个真题。大致如下
一个进程有3个线程,如果一个线程抛出oom,其他两个线程还能运行么?
先说一下答案,答案是还能运行
不瞒大家说,真在面试中,我遇到这一题,我估计也是答错。因为我初看到这一题,内心嘿嘿一笑,觉得这题是在考察JVM的内存结构。我第一反应是OOM的常见情况堆溢出,也就是下面的这种异常
  1. java.lang.OutOfMemoryError: Java heap space
先回忆一下,多线程中栈与堆是公有的还是私有的?回答如下
在多线程环境下,每个线程拥有一个栈和一个程序计数器。栈和程序计数器用来保存线程的执行历史和线程的执行状态,是线程私有的资源。其他的资源(比如堆、地址空间、全局变量)是由同一个进程内的多个线程共享。
也就是说,堆是线程共享。那么一个线程堆抛出OOM异常,我第一反应是另外两个线程也抛出OOM异常,毕竟堆是共有的,大家应该都抛出异常。于是,我机智的让 @大脸猫爱吃鱼写个代码去测试一下,结果我被啪啪啪打脸了。 测试代码伪如下 一个线程去构造堆溢出,每隔1S申请一次堆,代码长下面这样
  1. new Thread(() -> {
  2.     List<byte[]> list=new ArrayList<byte[]>();
  3.     while(true){
  4.         System.out.println(new Date().toString()+Thread.currentThread()+"==");
  5.         byte[] b = new byte[1024*1024*1];
  6.         list.add(b);
  7.         try {
  8.             Thread.sleep(1000);
  9.         } catch (Exception e) {
  10.             e.printStackTrace();
  11.         }
  12.     }
  13. }).start();
另一个线程,睡眠1秒然后输出就好,代码长下面这样
  1. new Thread(() -> {
  2.     while(true){
  3.         System.out.println(new Date().toString()+Thread.currentThread()+"==");
  4.         try {
  5.             Thread.sleep(1000);
  6.         } catch (Exception e) {
  7.             e.printStackTrace();
  8.         }
  9.     }
  10. }).start();
结果,输出是长下面这样的
大家发现了么,一个线程溢出了,其他线程还在跑,这好像和我们的认知不大一样。坦白说,我看到这个结果,瞬间觉得自己一世英名毁于一旦,从此无法抬起头来做人。没办法了,只能亮出工具来看一下了。 先说一下,在本例测试中,参数如下 -Xms16m -Xmx32m-Xms 初始堆内存  -Xmx 最大堆内存
接下来,亮出 JvisualVM看堆的变化,注意看上面那张图,抛出OOM的时间约在 00:11:45左右,因此我们需要重点关注 00:11:45左右的曲线变化,如下图所示
如图所示,我们仔细观察一下在 00:11:44~ 00:11:45之间曲线变化,你会发现使用堆的数量,突然间急剧下滑!这代表着一点,当一个线程抛出OOM异常后,它所占据的内存资源会全部被释放掉,从而不会影响其他线程的运行! 讲到这里大家应该懂了,此题的答案为一个线程溢出后,进程里的其他线程还能照常运行。注意了,这个例子我只演示了堆溢出的情况。如果是栈溢出,结论也是一样的,大家可自行通过代码测试。
补充:OOM发生时如果程序能正常处理这个异常情况,比如不再申请更多的内存或其它资源,或者放弃那个子任务或子线程,系统OOM状态是可以回到正常情况


丨极客文库, 版权所有丨如未注明 , 均为原创丨
本网站采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行授权
转载请注明原文链接:美团三面:一个线程OOM,进程里其他线程还能运行么?
喜欢 (0)
[247507792@qq.com]
分享 (0)
勤劳的小蚂蚁
关于作者:
温馨提示:本文来源于网络,转载文章皆标明了出处,如果您发现侵权文章,请及时向站长反馈删除。

您必须 登录 才能发表评论!

  • 精品技术教程
  • 编程资源分享
  • 问答交流社区
  • 极客文库知识库

客服QQ


QQ:2248886839


工作时间:09:00-23:00