Java內(nèi)存回收機(jī)制
在java中塘幅,內(nèi)存的分配大致分為:堆眼耀,棧骗爆、方法區(qū)、本地方法區(qū)挚币,程序計(jì)數(shù)器;本地方法區(qū)扣典,程序計(jì)數(shù)器妆毕,棧隨著線程的生滅而生滅,不需要我們關(guān)心內(nèi)存激捏,方法區(qū)和堆才是垃圾收集器所關(guān)注的部分设塔。
1 Java中對象是否存活算法
如何判斷一個(gè)對象可以被回收?在Java中远舅,采用的是可達(dá)性分析算法:通過一系列的"GC Roots"對象為起點(diǎn)闰蛔,向下搜索,搜索的路徑叫做引用鏈图柏,當(dāng)某些對象無法與任意一個(gè)"GC Roots"對象的引用鏈向連序六,則這個(gè)對象是不可用的。
GC Root對象
1蚤吹、棧中引用的對象
2例诀、方法區(qū)中類靜態(tài)屬性引用的對象
3、方法區(qū)中常亮引用的對象
4裁着、本地方法棧JNI引用的對象
Java中的四種引用
1繁涂、強(qiáng)引用(Strong Refernce):Java中最常用的引用,像二驰,new Object();只要強(qiáng)引用還在扔罪,對象就永遠(yuǎn)不會被回收被引用的對象;
2桶雀、軟引用(Soft Refernce):在系統(tǒng)發(fā)生內(nèi)存溢出異常之前矿酵,會將這類對象列進(jìn)回收范圍進(jìn)行第二次回收唬复,如果這次回收內(nèi)存依然不足,才會發(fā)生內(nèi)存溢出異常全肮。
3敞咧、弱引用(Weak Refernce):這類引用的對象,只能存活到下次GC之前辜腺,不論內(nèi)存是否充足休建,都會被回收;
4哪自、虛引用(Phantom Refernce):這類應(yīng)用完全不會對對象的什么周期構(gòu)成影響丰包,也無法通過虛引用獲取對象,該引用的目的是在GC回收時(shí)收到一個(gè)系統(tǒng)通知壤巷;
2 垃圾收集算法
在垃圾被回收以前邑彪,需要對對象進(jìn)行判斷處理,在Java中胧华,采用分代收集算法寄症,將對象分為新生代和老年代,針對這兩種情況矩动,分別采用不同的算法有巧;
1、新生代:采用復(fù)制算法悲没,將內(nèi)存按照1:1分為2部分篮迎,每次使用其中的一個(gè),當(dāng)使用的這個(gè)內(nèi)存用完示姿,就將還存活的對象復(fù)制到另一塊上甜橱,然后刪除這塊上的所有對象,優(yōu)點(diǎn)是實(shí)現(xiàn)簡單栈戳,運(yùn)行高效岂傲,不過在實(shí)際中,并不是按照1;1的比例分配子檀,而是按照8:1:1的比例分為3塊(Eden:Survivor:Survivor)镊掖,每次使用Eden和一個(gè)Survivor,回收時(shí)褂痰,將還存活的對象復(fù)制到另一塊Survivor上亩进,在刪除Eden和用過的Survivor;
2缩歪、老年代:采用"標(biāo)記-清理"或者"標(biāo)記-整理"算法镐侯。"標(biāo)記-清理",分為標(biāo)記和清理2個(gè)階段,先將需要清理的對象標(biāo)記苟翻,最后統(tǒng)一清理,不過有2大缺點(diǎn):效率問題骗污,空間碎片化崇猫;"標(biāo)記-整理",同樣分為2部分需忿,標(biāo)記诅炉,清理,在清理部分屋厘,不是直接清除垃圾涕烧,而是先將所以存活的對象向一端移動(dòng),最后在清理邊界以外的內(nèi)存汗洒。