最容易引发内存溢出的,就是系统创建出来的对象!
系统运行时,一直不停创建对象,然后大量对象会填满Eden。Eden满,就会触发一次YGC,然后存活对象进入S区:
高并发场景,导致YGC后很多请求还没处理完,存活对象太多,可能就在S区放不下,只能进入Old,Old很快就会满了:
一旦Old放满,就会触发Full GC。
假设YGC后,有一批存活对象,S放不下,就等着要进入Old,然后Old也满,就得等Old进行CMS GC,必须回收掉一批对象,才能让年轻代里存活的一批对象进去。
但Old GC后,依然存活下很多对象,这时若年轻代还有一批对象等着进Old,可Old空间还是不足,咋办? 只能内存溢出!
所以这时,Old都已满,你还要往里面放东西,而且触发Full GC回收了Old还是没足够内存空间,你却还要放, 那只能给你个内存溢出!JVM崩溃。
有限的内存中放了过多的对象,而且大多数都是存活的,此时即使GC过后还是大部分都存活,所以要继续放入更多对象已经不可能了,此时只能引发内存溢出。
发生内存溢出的主要场景:
综上,一般引发OOM,要不然是系统负载过高,要不然就是有内存泄露。
堆内存OOM的根本原因,即对象太多,且都是存活的,即使GC过后还是没有空间了,此时放不下新的对象,JVM只能选择崩溃!