1. 為什么要進(jìn)行垃圾回收?
- 創(chuàng)建的對(duì)象沒用時(shí)也不進(jìn)行回收的話,堆內(nèi)存很快就會(huì)被消耗殆盡,所以需要把一些沒有用的對(duì)象清理掉。
2. JVM GC 分為哪幾種?
- 分為三種,對(duì)新生代進(jìn)行的垃圾回收叫 minor GC,也叫YGC;對(duì)老年代進(jìn)行的垃圾回收叫 major GC;同時(shí)對(duì)新生代和老年代進(jìn)行的垃圾回收叫 full GC,簡(jiǎn)稱 FGC。
3. 如何判斷一個(gè)對(duì)象是否可以被回收?
有兩種方法判斷對(duì)象是否可回收,引用計(jì)數(shù)法和可達(dá)性分析算法。
- 引用計(jì)數(shù)法就是維護(hù)一個(gè)計(jì)數(shù)器,有引用指向?qū)ο髸r(shí)就加一,引用失效時(shí)就減一,引用為零就可以被回收。主流的 JVM 并沒有采用這種方式,因?yàn)楹茈y解決循環(huán)引用問題;
- 可達(dá)性分析算法是通過一系列 GC Roots 根節(jié)點(diǎn)集作為起始節(jié)點(diǎn),從這些節(jié)點(diǎn)根據(jù)引用關(guān)系向下搜索,搜索過程中經(jīng)過的路徑稱為引用鏈。如果一個(gè)對(duì)象到 GC Roots 之間沒有任何引用鏈,那么這個(gè)對(duì)象就稱為不可達(dá),就可以被回收。主流 JVM 采用的就是這種方式。
4. 哪些對(duì)象可以當(dāng)作 GC Roots?
- 系統(tǒng)類對(duì)象,也就是 jdk 自帶的類的對(duì)象;
5. 不可達(dá)的對(duì)象會(huì)被立即回收嗎?
- 不會(huì),一個(gè)對(duì)象至少要兩次判斷為不可達(dá)才會(huì)進(jìn)行回收,如果第一次判斷為不可達(dá),第二次又可達(dá),那這個(gè)對(duì)象就會(huì)復(fù)活。
6. 確定一個(gè)對(duì)象是要被回收的,那接下來如何怎么處理?
- 會(huì)加入到回收隊(duì)列中,然后 Finalizer 線程會(huì)觸發(fā)該對(duì)象的 finalize 方法對(duì)其進(jìn)行回收。Finalizer 線程并不會(huì)阻塞等待 finalize 結(jié)束,是為了不讓回收隊(duì)列阻塞。
7. 說一說垃圾回收的過程?
簡(jiǎn)單地說就是復(fù)制、清空、互換。詳細(xì)過程是:
- 新生代的伊甸園區(qū)對(duì)象如果滿了,就會(huì)觸發(fā) YGC,YGC 后還存活的對(duì)象,就會(huì)進(jìn)入 from 區(qū),同時(shí)清空伊甸園區(qū);
- 伊甸園區(qū)經(jīng)過一次 YGC 又滿了時(shí),會(huì)再次觸發(fā) YGC,會(huì)對(duì)伊甸園區(qū)和 from 區(qū)都進(jìn)行垃圾回收;
- 經(jīng)過這里兩次 YGC 還存活的對(duì)象,就會(huì)復(fù)制到 to 區(qū),對(duì)象年齡加一,然后清空伊甸園區(qū)和 from 區(qū),此時(shí) from 區(qū)和 to 區(qū)身份互換,誰空誰是 to;
- 當(dāng)對(duì)象年齡達(dá)到閾值,默認(rèn)是15,就會(huì)進(jìn)入老年代,老年代滿了就會(huì)觸發(fā) full GC,同時(shí)對(duì)新生代和老年代進(jìn)行垃圾回收;
- 觸發(fā) full GC 還沒騰出空間就會(huì)內(nèi)存溢出。
8. 有哪些垃圾回收算法?
常見的有四種,復(fù)制算法,標(biāo)記清除算法,標(biāo)記整理算法和分代回收算法。
- 新生代的 YGC 采用的就是復(fù)制算法,垃圾回收之后還存活的對(duì)象就會(huì)被復(fù)制到另一區(qū)域。它不會(huì)產(chǎn)生內(nèi)存碎片,但是內(nèi)存利用率不高;
- 標(biāo)記清除是先對(duì)可回收的對(duì)象進(jìn)行標(biāo)記,然后再進(jìn)行回收。它不會(huì)造成內(nèi)存空間的浪費(fèi),但是會(huì)產(chǎn)生內(nèi)存碎片;
- 標(biāo)記整理就是在標(biāo)記清除的基礎(chǔ)上,對(duì)內(nèi)存碎片進(jìn)行整理;
- 新生代對(duì)象存活率低,適合用復(fù)制算法;老年代對(duì)象比較多,所以不適合用復(fù)制算法,適合用標(biāo)記整理。這種不同內(nèi)存區(qū)域根據(jù)其特點(diǎn)采用不同垃圾回收算法的方式叫分代回收。
9. 你知道哪些垃圾回收器?
- serial 收集器:串行收集器,使用復(fù)制算法,新生代使用的,單線程,沒有線程交互的開銷,因此效率高,但是工作時(shí)會(huì)暫停其他所有線程;
- serial old收集器:serial 收集器的老年代版本,使用標(biāo)記整理算法;
- parNew 收集器:新生代收集器,使用復(fù)制算法,是 serial 收集器的多線程版本,性能更好;
- parNew old 收集器:parNew 收集器的老年代版本,使用標(biāo)記整理算法;
- parallel scavenge 收集器:使用復(fù)制算法,jdk8 新生代使用的默認(rèn)收集器,更關(guān)注吞吐量,能更高效地利用 CPU;
- CMS 收集器:老年代并發(fā)收集器,使用標(biāo)記清除算法,可以和用戶線程并發(fā)執(zhí)行。優(yōu)點(diǎn)是并發(fā)運(yùn)行,低停頓,缺點(diǎn)是會(huì)產(chǎn)生內(nèi)存碎片;
- G1 收集器:使用標(biāo)記整理算法的堆收集器,也就是新生代和老年代都可以使用這種收集器。