fullgc过于频繁有可能会形成oom,有可能不会。jvm
首先明确一下,这篇文章的重点是分析后面一种状况,即应用在频繁的fullgc,但并无出现oom。对象
咱们来想一下为何会出现fullgc,触发缘由有不少种,但归根到底都是由于内存空间不足了(system.gc的状况不考虑)。内存
系统在频繁的fullgc,但并无出现oom,说明每次回收的时候,确定清理了部份内存空间。那这里就有2种状况,gc以后清理的内存空间大不大?配置
一、若是每次gc以后剩余的空间不大,说明有一部分顽固对象一直无法被回收,致使可用内存变少。这种状况下很容易后续出现oom,好比说一次大对象的申请gc
二、若是每次gc以后剩余的空间比较大,意味着大部分对象都被清理了,可是系统又在频繁的fullgc,说明很快老年代又会涌入大量对象。这个时候就应该检查下jvm的参数配置,颇有多是新生代设置的过小了,致使不少应该在minor gc阶段就清理出去的对象留到了老年代,这种可能性是最大的时间
新生代能够分为eden、survivor0、survivor1,正常的对象分配都是在eden完成的,若是eden空间不够了,会触发一次minor gc,存活的对象放在s0或s1中。随着每次minor gc,存活的对象会不断的从s0迁到s1,再从s1迁到s0,这个过程通过几回以后,若是对象仍是存活的,就会晋升到老年代。vi
但若是新生代大小设置的过小,就会致使很是频繁的minor gc,s0->s1来回切换的速度加快,致使自己应该在minor gc就清理出去的对象跑到了老年代。参数
举个例子,正常状况下若是minor gc是1分钟一次,-XX:MaxTenuringThreshold默认配置是15的话,正常的小对象最长能够在新生代待15分钟左右,若是一个对象o的存活时间是5分钟,那它就能够在minor gc的时候被清理出去;但若是新生代设置太小,minor gc的频率降到10秒一次,那么o只能在新生代待150秒左右,而后就会晋升到老年代,这种对象一多,就会致使频繁的fullgc系统