什么是GC
GC是垃圾回收,JVM通過GC幫助回收沒用的內(nèi)存粘招。GC主要發(fā)生在堆上藻雌,偶爾也在方法區(qū)或者元數(shù)據(jù)區(qū)。
GC過程
- 找到?jīng)]用的內(nèi)存
- 清除沒用的內(nèi)存
如何找到?jīng)]用的內(nèi)存
- 引用計數(shù)算法怀喉,對象每多一次引用就加1,計數(shù)為0的代表可清除船响,不能解決相互引用且每次引用和去引用都伴隨加減法躬拢,性能較差躲履。
- 可達性分析算法,通過對GC-ROOTS對象進行引用分析聊闯,找出沒有指向該GC-ROOTS對象的引用鏈的對象即為可回收對象工猜。一個對象可以有多個root,下邊這些對象不會被垃圾回收所以可以當GC-ROOTS對象菱蔬,有
- 方法區(qū)中類靜態(tài)屬性引用的對象
- 方法區(qū)中常量引用的對象
- 本地方法棧引用的對象(本地變量表)
- 虛擬機棧中引用的對象(本地變量表)
如何清除沒用的內(nèi)存
- 標記-清除:分為兩個階段篷帅,標記階段和清除階段,標記階段拴泌,遍歷所有的根節(jié)點找到所有可達的對象魏身,未標記的就是需要被GC的。清除階段弛针,將沒有被標記的清除掉叠骑。缺點:速度慢李皇,內(nèi)存碎片削茁。會stop the world。適用于存活對象比回收對象少的場景掉房。
- 標記-整理(老年代):遍歷GC-ROOTS對象茧跋,標記可達的對象,將可達的對象移動到內(nèi)存的另一端卓囚,邊界外的內(nèi)存清空瘾杭。缺點:性能差,適用于存活對象少的場景哪亿。
- 復制算法(新生代):將內(nèi)存分為兩塊粥烁,每次只用一塊,每次GC將存活對象移動到另一塊蝇棉,這塊內(nèi)存全部刪除讨阻,缺點:浪費空間,適用于存活對象少的場景篡殷。
分代算法
內(nèi)存中的對象分為兩種钝吮,一種用后即焚,一種綠水長流板辽,所以要進行分代收集將內(nèi)存分為年輕代和老年代奇瘦,兩代采用不同的GC算法。
- 年輕代:大部分對象都是短命的劲弦,采用復制算法耳标。
- 老年代:大部分都是長命的,采用標記整理算法邑跪。
年輕代+老年代=堆內(nèi)存次坡,年輕代:老年代=1:2纲仍,年輕代=Eden(8)+survivor(1)+survivor(1)。
對象經(jīng)歷流程
new贸毕,出生在Eden區(qū)郑叠,經(jīng)過一次GC活下來了,和s1活下來的伙伴搬到s2,清空s1+Eden區(qū)明棍,調(diào)換s1和s2乡革,加一歲,現(xiàn)在到了s1,再次GC和Eden區(qū)的伙伴搬到s2,調(diào)換s1,s2加一歲摊腋,進入老年代的條件
- 到達年齡了(15)
- 對象體積太大
何時發(fā)生full gc
- System.gc()方法的調(diào)用 沸版。
- 老年代內(nèi)存不足時。
- 方法區(qū)或者元數(shù)據(jù)區(qū)內(nèi)存不足時兴蒸。