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系統