新聞中心
本篇內(nèi)容主要講解“什么是JVM垃圾收集器”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“什么是JVM垃圾收集器”吧!
成都創(chuàng)新互聯(lián)2013年至今,公司以成都網(wǎng)站建設(shè)、網(wǎng)站制作、系統(tǒng)開發(fā)、網(wǎng)絡(luò)推廣、文化傳媒、企業(yè)宣傳、平面廣告設(shè)計(jì)等為主要業(yè)務(wù),適用行業(yè)近百種。服務(wù)企業(yè)客戶超過千家,涉及國(guó)內(nèi)多個(gè)省份客戶。擁有多年網(wǎng)站建設(shè)開發(fā)經(jīng)驗(yàn)。為企業(yè)提供專業(yè)的網(wǎng)站建設(shè)、創(chuàng)意設(shè)計(jì)、宣傳推廣等服務(wù)。 通過專業(yè)的設(shè)計(jì)、獨(dú)特的風(fēng)格,為不同客戶提供各種風(fēng)格的特色服務(wù)。
1、簡(jiǎn)述Java垃圾回收機(jī)制
在java中,程序員是不需要顯示的去釋放一個(gè)對(duì)象的內(nèi)存的,而是由虛擬機(jī)自行執(zhí)行。在JVM中,有一個(gè)垃圾回收線程,它是低優(yōu)先級(jí)的,在正常情況下是不會(huì)執(zhí)行的,只有在虛擬機(jī)空閑或者當(dāng)前堆內(nèi)存不足時(shí),才會(huì)觸發(fā)執(zhí)行,掃面那些沒有被任何引用的對(duì)象,并將它們添加到要回收的集合中,進(jìn)行回收。
2、GC是什么?為什么要GC
GC 是垃圾收集的意思(Gabage Collection),內(nèi)存處理是編程人員容易出現(xiàn)問題的地方,忘記或者錯(cuò)誤的內(nèi)存
回收會(huì)導(dǎo)致程序或系統(tǒng)的不穩(wěn)定甚至崩潰,Java 提供的 GC 功能可以自動(dòng)監(jiān)測(cè)對(duì)象是否超過作用域從而達(dá)到自動(dòng)
回收內(nèi)存的目的,Java 語言沒有提供釋放已分配內(nèi)存的顯示操作方法。
3、垃圾回收的優(yōu)點(diǎn)和原理。并考慮2種回收機(jī)制
Java語言最顯著的特點(diǎn)就是引入了垃圾回收機(jī)制,它使java程序員在編寫程序時(shí)不再考慮內(nèi)存管理的問題。
由于有這個(gè)垃圾回收機(jī)制,java中的對(duì)象不再有“作用域”的概念,只有引用的對(duì)象才有“作用域”。
垃圾回收機(jī)制有效的防止了內(nèi)存泄露,可以有效的使用可使用的內(nèi)存。
垃圾回收器通常作為一個(gè)單獨(dú)的低級(jí)別的線程運(yùn)行,在不可預(yù)知的情況下對(duì)內(nèi)存堆中已經(jīng)死亡的或很長(zhǎng)時(shí)間沒有用過的對(duì)象進(jìn)行清除和回收。
程序員不能實(shí)時(shí)的對(duì)某個(gè)對(duì)象或所有對(duì)象調(diào)用垃圾回收器進(jìn)行垃圾回收。
垃圾回收有分代復(fù)制垃圾回收、標(biāo)記垃圾回收、增量垃圾回收。
4、垃圾回收器的基本原理是什么?垃圾回收器可以馬上回收內(nèi)存嗎?有什么辦法主動(dòng)通知虛擬機(jī)進(jìn)行垃圾回收?
對(duì)于GC來說,當(dāng)程序員創(chuàng)建對(duì)象時(shí),GC就開始監(jiān)控這個(gè)對(duì)象的地址、大小以及使用情況。
通常,GC采用有向圖的方式記錄和管理堆(heap)中的所有對(duì)象。通過這種方式確定哪些對(duì)象是"可達(dá)的",哪些對(duì)象是"不可達(dá)的"。當(dāng)GC確定一些對(duì)象為"不可達(dá)"時(shí),GC就有責(zé)任回收這些內(nèi)存空間。
可以。程序員可以手動(dòng)執(zhí)行System.gc(),通知GC運(yùn)行,但是Java語言規(guī)范并不保證GC一定會(huì)執(zhí)行。
5、Java 中都有哪些引用類型?
強(qiáng)引用:發(fā)生 gc 的時(shí)候不會(huì)被回收。
軟引用:有用但不是必須的對(duì)象,在發(fā)生內(nèi)存溢出之前會(huì)被回收。
弱引用:有用但不是必須的對(duì)象,在下一次GC時(shí)會(huì)被回收。
虛引用(幽靈引用/幻影引用):無法通過虛引用獲得對(duì)象,用 PhantomReference 實(shí)現(xiàn)虛引用,虛引用的用途是在 gc 時(shí)返回一個(gè)通知。
6、怎么判斷對(duì)象是否可以被回收?
垃圾收集器在做垃圾回收的時(shí)候,首先需要判定的就是哪些內(nèi)存是需要被回收的,哪些對(duì)象是「存活」的,是不可以被回收的;哪些對(duì)象已經(jīng)「死掉」了,需要被回收。
一般有兩種方法來判斷:
引用計(jì)數(shù)器法:為每個(gè)對(duì)象創(chuàng)建一個(gè)引用計(jì)數(shù),有對(duì)象引用時(shí)計(jì)數(shù)器 +1,引用被釋放時(shí)計(jì)數(shù) -1,當(dāng)計(jì)數(shù)器為 0 時(shí)就可以被回收。它有一個(gè)缺點(diǎn)不能解決循環(huán)引用的問題;
可達(dá)性分析算法:從 GC Roots 開始向下搜索,搜索所走過的路徑稱為引用鏈。當(dāng)一個(gè)對(duì)象到 GC Roots 沒有任何引用鏈相連時(shí),則證明此對(duì)象是可以被回收的。
7、在Java中,對(duì)象什么時(shí)候可以被垃圾回收
當(dāng)對(duì)象對(duì)當(dāng)前使用這個(gè)對(duì)象的應(yīng)用程序變得不可觸及的時(shí)候,這個(gè)對(duì)象就可以被回收了。
垃圾回收不會(huì)發(fā)生在永久代,如果永久代滿了或者是超過了臨界值,會(huì)觸發(fā)完全垃圾回收(Full GC)。如果你仔細(xì)查看垃圾收集器的輸出信息,就會(huì)發(fā)現(xiàn)永久代也是被回收的。這就是為什么正確的永久代大小對(duì)避免Full GC是非常重要的原因。
8、JVM中的永久代中會(huì)發(fā)生垃圾回收嗎
垃圾回收不會(huì)發(fā)生在永久代,如果永久代滿了或者是超過了臨界值,會(huì)觸發(fā)完全垃圾回收(Full GC)。如果你仔細(xì)查看垃圾收集器的輸出信息,就會(huì)發(fā)現(xiàn)永久代也是被回收的。這就是為什么正確的永久代大小對(duì)避免Full GC是非常重要的原因。請(qǐng)參考下Java8:從永久代到元數(shù)據(jù)區(qū)
(譯者注:Java8中已經(jīng)移除了永久代,新加了一個(gè)叫做元數(shù)據(jù)區(qū)的native內(nèi)存區(qū))
9、說一下 JVM 有哪些垃圾回收算法?
標(biāo)記-清除算法:標(biāo)記無用對(duì)象,然后進(jìn)行清除回收。缺點(diǎn):效率不高,無法清除垃圾碎片。
復(fù)制算法:按照容量劃分二個(gè)大小相等的內(nèi)存區(qū)域,當(dāng)一塊用完的時(shí)候?qū)⒒钪膶?duì)象復(fù)制到另一塊上,然后再把已使用的內(nèi)存空間一次清理掉。缺點(diǎn):內(nèi)存使用率不高,只有原來的一半。
標(biāo)記-整理算法:標(biāo)記無用對(duì)象,讓所有存活的對(duì)象都向一端移動(dòng),然后直接清除掉端邊界以外的內(nèi)存。
分代算法:根據(jù)對(duì)象存活周期的不同將內(nèi)存劃分為幾塊,一般是新生代和老年代,新生代基本采用復(fù)制算法,老年代采用標(biāo)記整理算法。
標(biāo)記-清除算法
標(biāo)記無用對(duì)象,然后進(jìn)行清除回收。
標(biāo)記-清除算法(Mark-Sweep)是一種常見的基礎(chǔ)垃圾收集算法,它將垃圾收集分為兩個(gè)階段:
標(biāo)記階段:標(biāo)記出可以回收的對(duì)象。
清除階段:回收被標(biāo)記的對(duì)象所占用的空間。
標(biāo)記-清除算法之所以是基礎(chǔ)的,是因?yàn)楹竺嬷v到的垃圾收集算法都是在此算法的基礎(chǔ)上進(jìn)行改進(jìn)的。
優(yōu)點(diǎn):實(shí)現(xiàn)簡(jiǎn)單,不需要對(duì)象進(jìn)行移動(dòng)。
缺點(diǎn):標(biāo)記、清除過程效率低,產(chǎn)生大量不連續(xù)的內(nèi)存碎片,提高了垃圾回收的頻率。
標(biāo)記-清除算法的執(zhí)行的過程如下圖所示
復(fù)制算法
為了解決標(biāo)記-清除算法的效率不高的問題,產(chǎn)生了復(fù)制算法。它把內(nèi)存空間劃為兩個(gè)相等的區(qū)域,每次只使用其中一個(gè)區(qū)域。垃圾收集時(shí),遍歷當(dāng)前使用的區(qū)域,把存活對(duì)象復(fù)制到另外一個(gè)區(qū)域中,最后將當(dāng)前使用的區(qū)域的可回收的對(duì)象進(jìn)行回收。
優(yōu)點(diǎn):按順序分配內(nèi)存即可,實(shí)現(xiàn)簡(jiǎn)單、運(yùn)行高效,不用考慮內(nèi)存碎片。
缺點(diǎn):可用的內(nèi)存大小縮小為原來的一半,對(duì)象存活率高時(shí)會(huì)頻繁進(jìn)行復(fù)制。
復(fù)制算法的執(zhí)行過程如下圖所示
標(biāo)記-整理算法
在新生代中可以使用復(fù)制算法,但是在老年代就不能選擇復(fù)制算法了,因?yàn)槔夏甏膶?duì)象存活率會(huì)較高,這樣會(huì)有較多的復(fù)制操作,導(dǎo)致效率變低。標(biāo)記-清除算法可以應(yīng)用在老年代中,但是它效率不高,在內(nèi)存回收后容易產(chǎn)生大量?jī)?nèi)存碎片。因此就出現(xiàn)了一種標(biāo)記-整理算法(Mark-Compact)算法,與標(biāo)記-整理算法不同的是,在標(biāo)記可回收的對(duì)象后將所有存活的對(duì)象壓縮到內(nèi)存的一端,使他們緊湊的排列在一起,然后對(duì)端邊界以外的內(nèi)存進(jìn)行回收。回收后,已用和未用的內(nèi)存都各自一邊。
優(yōu)點(diǎn):解決了標(biāo)記-清理算法存在的內(nèi)存碎片問題。
缺點(diǎn):仍需要進(jìn)行局部對(duì)象移動(dòng),一定程度上降低了效率。
標(biāo)記-整理算法的執(zhí)行過程如下圖所示
分代收集算法
當(dāng)前商業(yè)虛擬機(jī)都采用分代收集的垃圾收集算法。分代收集算法,顧名思義是根據(jù)對(duì)象的存活周期將內(nèi)存劃分為幾塊。一般包括年輕代、老年代和 永久代,如圖所示:
10、說一下 JVM 有哪些垃圾回收器?
如果說垃圾收集算法是內(nèi)存回收的方法論,那么垃圾收集器就是內(nèi)存回收的具體實(shí)現(xiàn)。下圖展示了7種作用于不同分代的收集器,其中用于回收新生代的收集器包括Serial、PraNew、Parallel Scavenge,回收老年代的收集器包括Serial Old、Parallel Old、CMS,還有用于回收整個(gè)Java堆的G1收集器。不同收集器之間的連線表示它們可以搭配使用。
Serial收集器(復(fù)制算法): 新生代單線程收集器,標(biāo)記和清理都是單線程,優(yōu)點(diǎn)是簡(jiǎn)單高效;
ParNew收集器 (復(fù)制算法): 新生代收并行集器,實(shí)際上是Serial收集器的多線程版本,在多核CPU環(huán)境下有著比Serial更好的表現(xiàn);
Parallel Scavenge收集器 (復(fù)制算法): 新生代并行收集器,追求高吞吐量,高效利用 CPU。吞吐量 = 用戶線程時(shí)間/(用戶線程時(shí)間+GC線程時(shí)間),高吞吐量可以高效率的利用CPU時(shí)間,盡快完成程序的運(yùn)算任務(wù),適合后臺(tái)應(yīng)用等對(duì)交互相應(yīng)要求不高的場(chǎng)景;
Serial Old收集器 (標(biāo)記-整理算法): 老年代單線程收集器,Serial收集器的老年代版本;
Parallel Old收集器 (標(biāo)記-整理算法): 老年代并行收集器,吞吐量?jī)?yōu)先,Parallel Scavenge收集器的老年代版本;
CMS(Concurrent Mark Sweep)收集器(標(biāo)記-清除算法): 老年代并行收集器,以獲取最短回收停頓時(shí)間為目標(biāo)的收集器,具有高并發(fā)、低停頓的特點(diǎn),追求最短GC回收停頓時(shí)間。
G1(Garbage First)收集器 (標(biāo)記-整理算法): Java堆并行收集器,G1收集器是JDK1.7提供的一個(gè)新收集器,G1收集器基于“標(biāo)記-整理”算法實(shí)現(xiàn),也就是說不會(huì)產(chǎn)生內(nèi)存碎片。此外,G1收集器不同于之前的收集器的一個(gè)重要特點(diǎn)是:G1回收的范圍是整個(gè)Java堆(包括新生代,老年代),而前六種收集器回收的范圍僅限于新生代或老年代。
11、詳細(xì)介紹一下 CMS 垃圾回收器?
CMS 是英文 Concurrent Mark-Sweep 的簡(jiǎn)稱,是以犧牲吞吐量為代價(jià)來獲得最短回收停頓時(shí)間的垃圾回收器。對(duì)于要求服務(wù)器響應(yīng)速度的應(yīng)用上,這種垃圾回收器非常適合。在啟動(dòng) JVM 的參數(shù)加上“-XX:+UseConcMarkSweepGC”來指定使用 CMS 垃圾回收器。
CMS 使用的是標(biāo)記-清除的算法實(shí)現(xiàn)的,所以在 gc 的時(shí)候回產(chǎn)生大量的內(nèi)存碎片,當(dāng)剩余內(nèi)存不能滿足程序運(yùn)行要求時(shí),系統(tǒng)將會(huì)出現(xiàn) Concurrent Mode Failure,臨時(shí) CMS 會(huì)采用 Serial Old 回收器進(jìn)行垃圾清除,此時(shí)的性能將會(huì)被降低。
12、新生代垃圾回收器和老年代垃圾回收器都有哪些?有什么區(qū)別?
新生代回收器:Serial、ParNew、Parallel Scavenge
老年代回收器:Serial Old、Parallel Old、CMS
整堆回收器:G1
新生代垃圾回收器一般采用的是復(fù)制算法,復(fù)制算法的優(yōu)點(diǎn)是效率高,缺點(diǎn)是內(nèi)存利用率低;老年代回收器一般采用的是標(biāo)記-整理的算法進(jìn)行垃圾回收。
13、簡(jiǎn)述分代垃圾回收器是怎么工作的?
分代回收器有兩個(gè)分區(qū):老生代和新生代,新生代默認(rèn)的空間占比總空間的 1/3,老生代的默認(rèn)占比是 2/3。
新生代使用的是復(fù)制算法,新生代里有 3 個(gè)分區(qū):Eden、To Survivor、From Survivor,它們的默認(rèn)占比是 8:1:1,它的執(zhí)行流程如下:
把 Eden + From Survivor 存活的對(duì)象放入 To Survivor 區(qū);
清空 Eden 和 From Survivor 分區(qū);
From Survivor 和 To Survivor 分區(qū)交換,F(xiàn)rom Survivor 變 To Survivor,To Survivor 變 From Survivor。
每次在 From Survivor 到 To Survivor 移動(dòng)時(shí)都存活的對(duì)象,年齡就 +1,當(dāng)年齡到達(dá) 15(默認(rèn)配置是 15)時(shí),升級(jí)為老生代。大對(duì)象也會(huì)直接進(jìn)入老生代。
老生代當(dāng)空間占用到達(dá)某個(gè)值之后就會(huì)觸發(fā)全局垃圾收回,一般使用標(biāo)記整理的執(zhí)行算法。以上這些循環(huán)往復(fù)就構(gòu)成了整個(gè)分代垃圾回收的整體執(zhí)行流程。
到此,相信大家對(duì)“什么是JVM垃圾收集器”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
本文題目:什么是JVM垃圾收集器
網(wǎng)站路徑:http://www.dlmjj.cn/article/pjohsd.html