Java 語(yǔ)言的一大特點(diǎn)就是可以自動(dòng)回收垃圾。
一下列舉了垃圾回收器的算法以及實(shí)現(xiàn)原理:
引用計(jì)數(shù)器算法
引用計(jì)數(shù)器的實(shí)現(xiàn)很簡(jiǎn)單,只要在每一個(gè)對(duì)象上添加一個(gè)整形的計(jì)數(shù)。當(dāng)有地方引用這個(gè)對(duì)象的時(shí)候,計(jì)數(shù)器+1,當(dāng)引用失效的時(shí)候,計(jì)數(shù)器-1。當(dāng)計(jì)數(shù)器為0,表示沒(méi)有對(duì)象引用,垃圾回收器會(huì)回收這個(gè)對(duì)象。
注意: 引用計(jì)數(shù)器不能處理循環(huán)引用的情況。
根搜索方法:
根搜索方法是通過(guò)一些“GC Roots”對(duì)象作為起點(diǎn),從這些節(jié)點(diǎn)開(kāi)始往下搜索,搜索通過(guò)的路徑成為引用鏈(Reference Chain),當(dāng)一個(gè)對(duì)象沒(méi)有被GC Roots的引用鏈連接的時(shí)候,說(shuō)明這個(gè)對(duì)象是不可用的。
GC Roots對(duì)象包括:
a) 虛擬機(jī)棧(棧幀中的本地變量表)中的引用的對(duì)象。
b) 方法區(qū)域中的類(lèi)靜態(tài)屬性引用的對(duì)象。
c) 方法區(qū)域中常量引用的對(duì)象。
d) 本地方法棧中JNI(Native方法)的引用的對(duì)象。
2. 標(biāo)記清除算法(Mark-Sweep)
標(biāo)記-清除算法分為兩個(gè)部分,一個(gè)是標(biāo)記,一個(gè)是刪除。
- 標(biāo)記階段: 確定所有需要回收的對(duì)象,并標(biāo)記。
- 清除階段: 清除階段緊隨標(biāo)記階段,回收所有標(biāo)記過(guò)的對(duì)象。
**特點(diǎn): **
標(biāo)注清除階段的效率不高,而且刪除過(guò)后,會(huì)產(chǎn)生很對(duì)不連續(xù)的內(nèi)存空間。
垃圾回收前:
[圖片上傳失敗...(image-43e8ff-1540177549428)]
垃圾回收后:
[圖片上傳失敗...(image-34f05b-1540177549428)]
標(biāo)記-復(fù)制算法(Copy)
復(fù)制算法是將內(nèi)存分為兩塊大小相等的內(nèi)存。在垃圾回收之后,將存活的對(duì)象復(fù)制到另一塊內(nèi)存空間,清除這塊內(nèi)存。
**特點(diǎn): **
復(fù)制算法運(yùn)行簡(jiǎn)單,實(shí)現(xiàn)高效,但是內(nèi)存利用率不高,每次只能使用一半?,F(xiàn)在的JVM使用復(fù)制的算法收集新生代,由于新生代大部分內(nèi)存時(shí)間都是短暫的,所以兩塊內(nèi)存的大小不是1:1(大概是8:1)。
垃圾回收之前:
[圖片上傳失敗...(image-328288-1540177549428)]
垃圾回收之后:
[圖片上傳失敗...(image-d73d4c-1540177549428)]
3. 標(biāo)記-整理算法(Mark-Compact)
標(biāo)記壓縮算法可標(biāo)記復(fù)制算法類(lèi)似,但是標(biāo)記整理算法不是將存活對(duì)象復(fù)制到另一半的內(nèi)存,而是將存活對(duì)象向內(nèi)存的一端移動(dòng),然后回收邊界以外的內(nèi)存。
**特點(diǎn): **
標(biāo)記整理算法提高了內(nèi)存的利用率,而且這種算法比較適合生命周期比較長(zhǎng)的老年代。
垃圾回收之前
[圖片上傳失敗...(image-b3c694-1540177549428)]
垃圾回收之后
[圖片上傳失敗...(image-5aa53e-1540177549428)]
分代收集( Generational Collection)
分代手機(jī)是將內(nèi)存分為新生代和老生代,根據(jù)個(gè)對(duì)象的存活特點(diǎn),每個(gè)待采用不同的算法。
新生代采用的是: 標(biāo)記-復(fù)制算法。兩塊內(nèi)存的大小比例大概(8:1)
老生代采用的是: 標(biāo)記-整理算法。