游客您好
第三方账号登陆
  • 点击联系客服

    在线时间:8:00-16:00

    客服电话

    020-85534346

    电子邮件

    81058337@qq.com
  • 码云社APP

    随时掌握码云社动态

  • 扫描二维码

    关注砺锋微信公众号

推荐阅读
品茶仙 初出江湖
未知星球 | 未知职业
  • 优质作者

    在社区持续发表优质文章
  • 圣诞老人

    圣诞节自动颁发
  • 金猪

    猪年自动颁发
  • 五一勋章

    五一劳动节在线用户
  • 关注0
  • 粉丝0
  • 帖子2

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

[复制链接]
品茶仙 发表于 1970-1-1 08:00:00 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
点击上方"java全栈技术"关注,每天学习一个java知识点
出自今年校招美团三面的一个真题。大致如下
一个进程有3个线程,如果一个线程抛出oom,其他两个线程还能运行么?
先说一下答案,答案是还能运行
不瞒大家说,真在面试中,我遇到这一题,我估计也是答错。因为我初看到这一题,内心嘿嘿一笑,觉得这题是在考察JVM的内存结构。我第一反应是OOM的常见情况堆溢出,也就是下面的这种异常
java.lang.OutOfMemoryError: Java heap space
先回忆一下,多线程中栈与堆是公有的还是私有的?回答如下
在多线程环境下,每个线程拥有一个栈和一个程序计数器。栈和程序计数器用来保存线程的执行历史和线程的执行状态,是线程私有的资源。其他的资源(比如堆、地址空间、全局变量)是由同一个进程内的多个线程共享。
也就是说,堆是线程共享。那么一个线程堆抛出OOM异常,我第一反应是另外两个线程也抛出OOM异常,毕竟堆是共有的,大家应该都抛出异常。于是,我机智的写个代码去测试一下,结果我被啪啪啪打脸了。 测试代码伪如下 一个线程去构造堆溢出,每隔1S申请一次堆,代码长下面这样
QIrZp7AWlc0lIR0G.jpg





另一个线程,睡眠1秒然后输出就好,代码长下面这样
PVKCBCVvO5T70007.jpg





结果,输出是长下面这样的
xXz1ND1nbvxHD1yn.jpg





大家发现了么,一个线程溢出了,其他线程还在跑,这好像和我们的认知不大一样。坦白说,我看到这个结果,瞬间觉得自己一世英名毁于一旦,从此无法抬起头来做人。没办法了,只能亮出工具来看一下了。 先说一下,在本例测试中,参数如下 -Xms16m -Xmx32m-Xms 初始堆内存 -Xmx 最大堆内存
接下来,亮出 JvisualVM看堆的变化,注意看上面那张图,抛出OOM的时间约在00:11:45左右,因此我们需要重点关注 00:11:45左右的曲线变化,如下图所示
zGETK0dekBKdGvk9.jpg



如图所示,我们仔细观察一下在 00:11:44~ 00:11:45之间曲线变化,你会发现使用堆的数量,突然间急剧下滑!这代表着一点,当一个线程抛出OOM异常后,它所占据的内存资源会全部被释放掉,从而不会影响其他线程的运行! 讲到这里大家应该懂了,此题的答案为一个线程溢出后,进程里的其他线程还能照常运行。注意了,这个例子我只演示了堆溢出的情况。如果是栈溢出,结论也是一样的,大家可自行通过代码测试。
补充:OOM发生时如果程序能正常处理这个异常情况,比如不再申请更多的内存或其它资源,或者放弃那个子任务或子线程,系统OOM状态是可以回到正常情况
文章来自:打杂的ZRJ
码云社-用代码改变世界!
回复 关闭延时

使用道具 举报

精彩评论21

趁早起飞 发表于 2019-4-3 16:04:37 | 显示全部楼层
抛出OOM之后,线程会被终止,并触发FullGC
码云社-用代码改变世界!
回复

使用道具 举报

溜冰小屋TA745 发表于 2019-4-3 16:06:56 | 显示全部楼层
很多大公司都是面试造航母。
码云社-用代码改变世界!
回复

使用道具 举报

戴孟刀炎 发表于 2019-4-3 16:10:54 | 显示全部楼层
上面的代码list是线程内部变量, 如果作为全局静态变量,效果会怎样?
码云社-用代码改变世界!
回复

使用道具 举报

弘苑95 发表于 2019-4-3 16:13:32 | 显示全部楼层
能运行,但不一定能正确运行。因为HEAP爆了,可能有些对象就丢了,其他线程如果刚好要用到这些对象,可能就会抛出异常,从而不能正确运行。
码云社-用代码改变世界!
回复

使用道具 举报

天赐文犬 发表于 2019-4-3 16:16:46 | 显示全部楼层
oom之后,gc回收有多快?其他线程如果不睡眠一直申请堆内存会不会直接崩?个人看法,这要看其他线程的情况,如果一直申请堆内存,在堆爆掉的时候,会影响其他线程的吧
码云社-用代码改变世界!
回复

使用道具 举报

考拉拉拉拉拉 发表于 2019-4-3 16:19:41 | 显示全部楼层
我只知道JAVA的线程是自己实现的,如果你考其它语言就不一定了
码云社-用代码改变世界!
回复

使用道具 举报

dongpengcizhuan 发表于 2019-4-3 16:22:41 | 显示全部楼层
作者,你用的jdk是什么版本?
码云社-用代码改变世界!
回复

使用道具 举报

我是你baba 发表于 2019-4-3 16:26:38 | 显示全部楼层
这个是要看情况的,如果其他线程也申请堆空间,你看看会不会异常。
码云社-用代码改变世界!
回复

使用道具 举报

619505038 发表于 2019-4-3 16:29:34 | 显示全部楼层
一个web系统oom,对应服务会不可用,你告诉我怎么处理让系统可用
码云社-用代码改变世界!
回复

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies 上传

本版积分规则

CODESEEDING(码云社)一家致力于程序员成长、以内容为核心、以提问为引导的多元化成长社区。我们在线上为技术爱好者提供了一个优质的交流氛围环境,在线下同样和众多高校联合开办了技术沙龙品牌。
020-85534346
关注我们
  • 访问移动H5版
  • 官方微信公众号

码云社 - CODESEEDING 2.0© 2018-2019 码云社. TOOBUG ( 粤ICP备16114193号-3 )