很多人第一次遇到这个问题的时候,第一反应估计是不能运行。
但是口说无凭啊,还是得去实践一下。
先捋一捋思路,每一个线程都拥有一个栈和一个程序计数器。JVM 栈和程序计数器用来保存线程的执行历史和线程的执行状态,是线程私有资源。而其他资源(比如堆、地址空间、全局变量)是由同一个进程内的多个线程共享。
也就是说堆是线程共享的。那么一个线程堆抛出 OOM 异常,第一反应是另外两个线程也抛出OOM异常,毕竟堆是共有的,都会抛出异常。但想法很好,实际上却不是。
实践出真知,先来一下测试代码,用一个线程去造成堆溢出,每隔 1s 申请一次堆。
1 | new Thread(() -> { |
另一个线程,休眠 1s
1 | new Thread(() -> { |
测试中 JVM 堆大小如下
1 | -Xms16m -Xmx32m |
结果可想而知:一个线程发生 OOM ,其他线程还在运行。
一个线程溢出后,进程里的其他线程还能照常运行。