上一章我們已經(jīng)探討過(guò)GC的各個(gè)算法,那么垃圾搜集器是什么呢?
通俗的講,使用編程語(yǔ)言將算法實(shí)現(xiàn)出來(lái),產(chǎn)生的程序就是垃圾搜集器了。既然談到了編程語(yǔ)言的實(shí)現(xiàn),那么在討論垃圾搜集器的時(shí)候,就已經(jīng)涉及到具體的虛擬機(jī)實(shí)現(xiàn)了。
或許有不少做java開(kāi)發(fā)的猿友還不知道,我們平時(shí)使用的JDK中,默認(rèn)的JVM是hotspot,換句話說(shuō),我們大部分時(shí)候使用的JVM都是hotspot的實(shí)現(xiàn)版本,因此,本次LZ討論垃圾搜集器都是基于hotspot版JVM來(lái)進(jìn)行的,請(qǐng)各位猿友要知曉這一點(diǎn)。
更直觀的,我們可以在我們平時(shí)開(kāi)發(fā)的機(jī)子上,輸入java -version來(lái)查看JVM的版本,相信大部分猿友對(duì)這個(gè)命令都不陌生吧,LZ的機(jī)子截圖如下。
上面我們已經(jīng)提到,垃圾搜集器實(shí)際就是算法的編程語(yǔ)言實(shí)現(xiàn)。既然牽扯到編程語(yǔ)言,那么必然離不開(kāi)線程,而且我們?cè)谇懊嬷v解算法的時(shí)候也一直假設(shè)是一條GC線程在做著GC的事情。
因此,垃圾搜集器大致分為以下三類(lèi)。
串行搜集器(serial collector):它只有一條GC線程,且就像前面說(shuō)的,它在運(yùn)行的時(shí)候需要暫停用戶(hù)程序(stop the world)。
并行搜集器(parallel collector):它有多條GC線程,且它也需要暫停用戶(hù)程序(stop the world)。
并發(fā)搜集器(concurrent collector):它有一條或多條GC線程,且它需要在部分階段暫停用戶(hù)程序(stop the world),部分階段與用戶(hù)程序并發(fā)執(zhí)行。
看完上面的定義,相信有一部分猿友已經(jīng)蒙了,一會(huì)單線程,一會(huì)多線程,一會(huì)串行,一會(huì)并行,一會(huì)并發(fā),這都神馬玩意?
單線程和多線程就不必多說(shuō)了,這個(gè)很好理解,串行與并行也比較好理解,難于分辨的就是并行(parallel)與并發(fā)(concurrent)。
對(duì)于很多有關(guān)并發(fā)的解釋?zhuān)琇Z覺(jué)得有一個(gè)最貼切。它是這么解釋的,并發(fā)就是兩個(gè)任務(wù)A和B需要相互獨(dú)立的運(yùn)行,并且A任務(wù)先開(kāi)始后,B任務(wù)在A任務(wù)結(jié)束之前開(kāi)始了。
并發(fā)本身是比較好理解的,那么它與并行的關(guān)系與區(qū)別是什么呢?
事實(shí)上,并行是并發(fā)的一種實(shí)現(xiàn)方式。LZ覺(jué)得這么說(shuō)各位可能會(huì)更好理解,當(dāng)然,并行并不是并發(fā)的唯一實(shí)現(xiàn)方式,還有一種就是我們所熟悉的時(shí)間片切換。也就是A任務(wù)執(zhí)行一會(huì),B任務(wù)執(zhí)行一會(huì),交替執(zhí)行。
并行必須在多核多處理器或者分布式系統(tǒng)(本質(zhì)還是多核多處理器)的前提下才能發(fā)生,而交替執(zhí)行或者說(shuō)時(shí)間片切換是在單核的處理器上發(fā)生的。
我們上面已經(jīng)簡(jiǎn)單探討了垃圾搜集器的分類(lèi),在hotspotJVM中,每一個(gè)種類(lèi)的垃圾搜集器都有對(duì)應(yīng)的實(shí)現(xiàn),如下。
串行搜集器的實(shí)現(xiàn):serial(用于新生代,采用復(fù)制算法)、serial old(用于年老代,采用標(biāo)記/整理算法)
并行搜集器的實(shí)現(xiàn):ParNew(用于新生代,采用復(fù)制算法)、Parallel Scavenge(用于新生代,采用復(fù)制算法)、Parallel old(用于年老代,采用標(biāo)記/整理算法)
并發(fā)搜集器的實(shí)現(xiàn):concurrent mark sweep[CMS](用于年老代,采用標(biāo)記/清除算法)
可以看到,上面每一種垃圾搜集器都是針對(duì)不同內(nèi)存區(qū)域所設(shè)計(jì)的,因?yàn)樗鼈儾捎玫乃惴ú煌?,凡是用于新生代的都是使用的?fù)制算法,而用于年老代的都是使用的標(biāo)記/清除或者標(biāo)記/整理算法。
在實(shí)際應(yīng)用中,我們需要給JVM的新生代和年老代分別選擇垃圾搜集器,可以看到無(wú)論是新生代還是年老代都分別有三種實(shí)現(xiàn),換句話說(shuō),我們應(yīng)該有3*3=9種選擇。但是,事實(shí)并非如此。
事實(shí)上,這六種垃圾搜集器只有六種選擇,因?yàn)橛械睦鸭饔捎诰唧w實(shí)現(xiàn)的方式等一系列原因無(wú)法在一起工作,如下圖。
針對(duì)上圖,紅的就是串行搜集器,綠的是并行搜集器,唯一一個(gè)黃的是并發(fā)搜集器。上面三個(gè)是新生代的搜集器,下面三個(gè)是年老代的搜集器。兩者之間有連線,則表示兩者可以配合工作。
這六種組合并沒(méi)有說(shuō)哪個(gè)組合最強(qiáng),哪個(gè)組合最弱,還是那句話,只有最合適的,沒(méi)有最好的。因此這就需要我們對(duì)每一種組合有一定的認(rèn)識(shí),才能在使用的時(shí)候選擇更適合的垃圾搜集器。
|
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注