首先说一下OOM的可能
1、堆溢出(“java.lang.OutOfMemoryError: Java heap space”)
2、永久带溢出(“java.lang.OutOfMemoryError:Permgen space”)
3、不能创建线程(“java.lang.OutOfMemoryError:Unable to create new native thread”)
写个代码测一测
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class JvmThread {
public static void main(String[] args) {
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();
// 线程二
new Thread(() -> {
while (true) {
System.out.println(new Date().toString() + Thread.currentThread() + "==");
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
设置好JVM参数
Mon Apr 12 14:42:18 CST 2018Thread[Thread-1,5,main]==
Mon Apr 12 14:42:18 CST 2018Thread[Thread-0,5,main]==
Mon Apr 12 14:42:19 CST 2018Thread[Thread-1,5,main]==
Mon Apr 12 14:42:19 CST 2018Thread[Thread-0,5,main]==
Exception in thread "Thread-0" java.lang.OutOfMemoryError: Java heap space
at com.test.util.JvmThread.lambda$main$0(JvmThread.java:21)
at com.test.util.JvmThread$$Lambda$1/521645586.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
Mon Apr 12 14:42:20 CST 2018Thread[Thread-1,5,main]==
Mon Apr 12 14:42:21 CST 2018Thread[Thread-1,5,main]==
Mon Apr 12 14:42:22 CST 2018Thread[Thread-1,5,main]==
通过打印可以看到
在14:42:05~14:42:25之间曲线变化, 使用堆的数量,突然间急剧下滑
这表示:当一个线程抛出OOM异常后,它所占据的内存资源会全部被释放掉,从而不会影响其他线程的运行
一个线程溢出后,进程里的其他线程还能照常运行,如果是栈溢出,结论也是一样的,大家可自行通过代码测试。
总结:其实发生OOM的线程一般情况下会死亡,也就是会被终结掉,该线程持有的对象占用的heap都会被gc了,释放内存。因为发生OOM之前要进行gc,就算其他线程能够正常工作,也会因为频繁gc产生较大的影响。