前言
OOM之后,线程不会死亡。
内容
其实发生OOM的线程一般情况下会死亡,也就是会被终结掉,该线程持有的对象占用的heap都会被gc了,释放内存。因为发生OOM之前要进行gc,就算其他线程能够正常工作,也会因为频繁gc产生较大的影响。
理解
参考评论
我觉得应该这样理解:线程一一直在分配对象,并且这些对象有强引用指着,所以在线程一的运行过程中这部分内存一直无法释放,直到 heap 满。这时候触发 full GC 尝试回收,发现无法回收,JVM 抛出 OutOfMemoryError。由于线程一没有 catch 这个 error,因此线程一退出。此时线程二仍在执行,并且还会分配对象。很快又触发一次 GC,这时,由于线程一中的 list 已经没有强引用指着它,所以内存得以释放。
这里内存被释放的主要原因还是 list 是局部变量,线程退出后对象没有强引用指着,所以可以释放。文章中的“当一个线程抛出OOM异常后,它所占据的内存资源会全部被释放掉”我觉得是不准确的,因为首先:1. 想要释放掉线程占据的内存资源,必须确认这部分是线程独占的,否则是不能释放的(因为别的线程还会用到);2. 很难断定哪些内存是线程独占的,GC 的时候也只是知道一个对象是不是被 GC root 指着(包括直接和间接),只要指着,就是活的,就不能回收。