Jvm內存回收
一、什麽內存會被回收
可達性分析算法
通過一系列的GC ROOT的對象作為超始點,從這些節點開始向下搜索,搜索所走的路徑稱為"引用鏈",當一個對象到GC ROOT之間沒有任何引用鏈,則會對該對象進行一次標記,說明對象暫時是沒用的
GC ROOT對象指:
虛擬機棧(棧幀中的局部變量表)中的引用對象
方法區中靜態屬性的引用對象
方法區中常量引用對象
本地方法棧中JNI引用對象
剛剛上面所說,經過可達性分析算法後,會對該對象進行一次標記,只能說明對象暫時是沒用的,一個對象宣告死亡最少要經歷兩次標記,如果經過可達性分析算法後,如果對象到 GC ROOT 之間沒有引用鏈,將會進行一次標記並且進行一次篩選,篩選的條件:
此對象沒有重寫finalize()方法
finalize()方法已經被執行過一次
如果滿足這兩個條件,說明沒有必要執行
如果這個對象有實現finalize()方法,那這個對象將會放置在一個叫做F-QUEUE的隊列中,由虛擬機自動建立,低優先級的執行。
二、什麽時候回收
Jvm堆內存可分為:新生代(Eden、From、To),老年代,永久代
新生代:
新生代可分為Eden、From、To空間,占比:8:1:1,可以通過SurvivorRatio進行設置
當Eden空間滿了後,會進行YGC,采用復制算法(ParNew、Parallel Scavenge),將還存活的對象復制到Survivor空間,然後清理掉Eden空間
老年代:
當新生代產生YGC時,會將前面Survivor中還存活的對象復制到老年代,如果此時,老年代空間不足(老年代使用了92%,CMS會被激活),會進行Full GC,采用(CMS、Parallel old),
CMS分為四個過程:
初次標記(STW)
並發標記
重新標記(STW)
並發清除
Jvm內存回收