OOM:Out Of Memory。
在多线程环境下,每个线程拥有一个栈和一个程序计数器。栈和程序计数器用来保存线程的执行历史和线程的执行状态,是线程私有的资源,也就是说,堆是线程共享。其他的资源(比如堆、地址空间、全局变量)是由同一个进程内的多个线程共享。当进程中有N个线程,且其中一个线程抛出内存溢出的异常后,其他线程会不会停止呢?
话不多说,亮代码:
//我负责检测线程是否停止
public void method1() {
while(true){
System.out.println(new Date().toString()+Thread.currentThread()+"==");
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
//我负责搞事情,保证让内存迅速溢出
public void method2() {
List<byte[]> list=new ArrayList<byte[]>();
while(true){
System.out.println(new Date().toString()+Thread.currentThread()+"==");
byte[] b = new byte[1024*1024*512];
list.add(b);
System.err.println("已经申请了:"+list.size()/2+"G内存");
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
好了,看看结果如何:
//注意看线程:Thread-0,Thread-1
Sun Sep 23 10:18:11 GMT+08:00 2018Thread[Thread-0,5,main]==
Sun Sep 23 10:18:11 GMT+08:00 2018Thread[Thread-1,5,main]==
已经申请了:0G内存
Sun Sep 23 10:18:12 GMT+08:00 2018Thread[Thread-0,5,main]==
Sun Sep 23 10:18:12 GMT+08:00 2018Thread[Thread-1,5,main]==
Exception in thread "Thread-1" java.lang.OutOfMemoryError: Java heap space
at 多线程之OOM.MyObject.method2(MyObject.java:24)
at 多线程之OOM.MyObject$2.run(MyObject.java:47)
at java.lang.Thread.run(Unknown Source)
Sun Sep 23 10:18:13 GMT+08:00 2018Thread[Thread-0,5,main]==
Sun Sep 23 10:18:14 GMT+08:00 2018Thread[Thread-0,5,main]==
结果显示:负责搞事情的线程一很快就因为OOM把自己给作死了,而作为检测线程的线程二仍然坚挺地活着。也即是说:进程中有N个线程,其中一个线程因为OOM死掉了,其余线程依然继续执行而不是停止。
查阅相关资料:原来当一个线程抛出OOM异常后,它所占据的内存资源会全部被释放掉,从而不会影响其他线程的运行!