【原创】一个线程oom,进程里其他线程还能运行吗?
引言
这题是一个网友@大脸猫爱吃鱼给我的提问,出自今年校招美团三面的一个真题。大致如下
一个进程有3个线程,如果一个线程抛出oom,其他两个线程还能运行么?
先说一下答案,答案是还能运行
不瞒大家说,真在面试中,我遇到这一题,我估计也是答错。因为我初看到这一题,内心嘿嘿一笑,觉得这题是在考察JVM的内存结构。我第一反应是OOM的常见情况堆溢出,也就是下面的这种异常
java.lang.OutOfMemoryError: Java heap space
先回忆一下,多线程中栈与堆是公有的还是私有的?回答如下
在多线程环境下,每个线程拥有一个栈和一个程序计数器。栈和程序计数器用来保存线程的执行历史和线程的执行状态,是线程私有的资源。其他的资源(比如堆、地址空间、全局变量)是由同一个进程内的多个线程共享。
也就是说,堆是线程共享。那么一个线程堆抛出OOM异常,我第一反应是另外两个线程也抛出OOM异常,毕竟堆是共有的,大家应该都抛出异常。于是,我机智的让@大脸猫爱吃鱼写个代码去测试一下,结果我被啪啪啪打脸了。
测试代码伪如下
一个线程去构造堆溢出,每隔1秒申请一次堆,代码长下面这样
new Thread(() -> {
List<byte[]> list=new ArrayList<byte[]>();
while(true){
System.out.println(new Date().toString()+Thread.currentThread()+"==");
byte[] b = new byte[1024*1024*1];
list.add(b);
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
另一个线程,睡眠1秒然后输出就好,代码长下面这样
new Thread(() -> {
while(true){
System.out.println(new Date().toString()+Thread.currentThread()+"==");
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
结果,输出是长下面这样的

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

如图所示,我们仔细观察一下在00:11:44~00:11:45之间曲线变化,你会发现使用堆的数量,突然间急剧下滑!这代表着一点,当一个线程抛出OOM异常后,它所占据的内存资源会全部被释放掉,从而不会影响其他线程的运行!
讲到这里大家应该懂了,此题的答案为一个线程溢出后,进程里的其他线程还能照常运行。注意了,这个例子我只演示了堆溢出的情况。如果是栈溢出,结论也是一样的,大家可自行通过代码测试。
说时迟,那时快。一个机智的网友又给我提了一个问题?
如果主线程抛异常退出了,子线程还能运行么?
ok,这个问题要从子线程和主线程的关系讲起。
先来一个定义
线程不像进程,一个进程中的线程之间是没有父子之分的,都是平级关系。即线程都是一样的, 退出了一个不会影响另外一个。
因此,答案是如果主线程抛异常退出了,子线程还能运行。
但是有一个例外情况,如果这些子线程都是守护线程,那么子线程会随着主线程结束而结束。
【原创】一个线程oom,进程里其他线程还能运行吗?的更多相关文章
- 一个线程oom,进程里其他线程还能运行吗?
线程之间互相不影响:守护线程生活周期相同 引言 这题是一个网友@大脸猫爱吃鱼给我的提问,出自今年校招美团三面的一个真题.大致如下 一个进程有3个线程,如果一个线程抛出oom,其他两个线程还能运行么? ...
- Python 开启线程的2中方式,线程VS进程(守护线程、互斥锁)
知识点一: 进程:资源单位 线程:才是CPU的执行单位 进程的运行: 开一个进程就意味着开一个内存空间,存数据用,产生的数据往里面丢 线程的运行: 代码的运行过程就相当于运行了一个线程 辅助理解:一座 ...
- 进击的Python【第九章】:paramiko模块、线程与进程、各种线程锁、queue队列、生产者消费者模型
一.paramiko模块 他是什么东西? paramiko模块是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接. 先来个实例: import param ...
- 12 并发编程-(线程)-线程queue&进程池与线程池
queue 英 /kjuː/ 美 /kju/ 队列 1.class queue.Queue(maxsize=0) #队列:先进先出 import queue q=queue.Queue() q.put ...
- day35:线程队列&进程池和线程池&回调函数&协程
目录 1.线程队列 2.进程池和线程池 3.回调函数 4.协程:线程的具体实现 5.利用协程爬取数据 线程队列 1.线程队列的基本方法 put 存 get 取 put_nowait 存,超出了队列长度 ...
- GIL全局解释器锁+GIL全局解释器锁vs互斥锁+定时器+线程queue+进程池与线程池(同步与异步)
以多线程为例写个互斥锁 from threading import Thread ,Lockimport timemutex = Lock() n = 100 def task(): global n ...
- 计算机必知必会:进程process与线程thread 进程定义为一个正在运行的程序的实例
http://www.nowamagic.net/librarys/veda/detail/1741进程和线程这对概念的理解也是很难的,至今网络上可查的资料对其的理解出入都挺大,在不同的操作系统中,如 ...
- paramiko模块,线程,进程
关于paramiko模块 paramiko是基于Python实现的ssh2远程安全连接,支持认证及密钥方式远程执行命令.文件传输,中间ssh代理等 paramiko的安装: 安装好之后,用parami ...
- Linux 线程与进程,以及通信
http://blog.chinaunix.net/uid-25324849-id-3110075.html 部分转自:http://blog.chinaunix.net/uid-20620288-i ...
随机推荐
- redmine screenshot paste(粘贴截图)
前言 本文所使用的 redmine 3.1.x 查看redmine版本:以管理员帐号登录 – 点 管理 – 点 信息,示例如下: 在线插件库 插件仓库,可以下载丰富的插件: http://www.re ...
- 看到一个想收藏的的AJAX小列子
用户登录的验证可以使用 form 表单提交,也可以使用 ajax 技术异步提交. AJAX 即 Asynchronous Javascript And XML(异步 JavaScript 和 XML) ...
- Windows7安装Bitvise开启ssh服务
Windows7安装Bitvise开启ssh服务 by:铁乐猫 在Liunx和windows10上配置SSH服务是一件很容易的事,毕竟系统己经自带了ssh的服务功能. 不过在windows7上可不容易 ...
- February 12th, 2018 Week 7th Monday
One man's fault is another man's lesson. 前车之覆,后车之鉴. We make mistakes every day, large or small, fail ...
- Spring的AOP开发的相关术语
转载自 https://www.cnblogs.com/ltfxy/p/9873618.html SpringAOP简介: AOP思想最早是由AOP联盟组织提出的.Spring使用这种思想最好的框架. ...
- WIN10中DOCKER的安装
1.docker的安装 环境准备 Docker for Windows是一个Docker Community Edition(CE)应用程序.Docker for Windows安装包包含了在Wind ...
- C. Magic Ship cf 二分
C. Magic Ship time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...
- 概率期望dp
对于概率dp,我一直都弄得不是特别明白,虽然以前也有为了考试去突击过,但是终究还是掌握得不是很好,所以决定再去学习一遍,把重要的东西记录下来. 1.hdu4405 Description 在一个 \( ...
- UVA11491-Erasing ans Winning(贪心)
Problem UVA11491-Erasing ans Winning Accept: 799 Submit: 5753Time Limit: 3000 mSec Problem Descript ...
- 极光推送(C#)
推荐使用appSetting 加载这两个参数 webConfig: <appSettings> <add key="AppKey" value="ccc ...