<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    paulwong

    HotSpot 的垃圾收集 - 轉(zhuǎn)

    從J2SE 5.0開(kāi)始,HotSpot JVM共包含四種垃圾收集器,它們?nèi)炕诜执惴ā?br />一、代的劃分
    HotSpot JVM中內(nèi)存被劃分為三代:年幼代(young generation)、年長(zhǎng)代(old generation)和永久代(permanent generation)。從邏輯上講,年幼代和年長(zhǎng)代共同構(gòu)成了Java堆,而永久代則被稱為方法區(qū)(method area)。除了一些大對(duì)象可能在年長(zhǎng)區(qū)中直接分配外,大部分對(duì)象都在年幼區(qū)中創(chuàng)建;而年長(zhǎng)區(qū)除了那些直接創(chuàng)建的大對(duì)象外,大部分對(duì)象都是在年幼區(qū)中歷經(jīng)幾次垃圾收集而幸免于難后被提升過(guò)來(lái)的。永久代中則保存著已載入類型的相關(guān)信息,包含了類、方法和其他一些內(nèi)部使用的元數(shù)據(jù),所有這些信息同樣以對(duì)象的形式來(lái)組織和表示,雖然這些對(duì)象并不是Java對(duì)象,但是它們卻象Java對(duì)象一樣可以被同樣的垃圾收集器所收集;另外,java.lang.String類所管理的內(nèi)在化的字符串緩存池也在該代中分配;雖然名字叫做“永久”代,但其中的對(duì)象并不是永久的,只是沿用了歷史名稱而已。
    年幼代由一個(gè)伊甸區(qū)(Eden Space)和兩個(gè)更小的生還區(qū)(Survivor Space)組成,如下圖所示(該圖為縮略圖,請(qǐng)點(diǎn)擊察看原圖)。大部分對(duì)象在伊甸區(qū)中創(chuàng)建,少數(shù)大對(duì)象可能在年長(zhǎng)代中直接創(chuàng)建。生還區(qū)中保存的對(duì)象是歷經(jīng)一次或多次對(duì)年幼代的垃圾收集而未死的幸存者,并且在被認(rèn)為已足夠成熟而提升到年長(zhǎng)代之前,它們?nèi)杂性谏院蟮哪炒卫占^(guò)程中犧牲的可能。除非處在垃圾收集過(guò)程當(dāng)中,兩個(gè)生還區(qū)中只有一個(gè)用來(lái)容納這些幸存者,另一個(gè)則保持為空。
    JVM中的垃圾收集" alt="HotSpot JVM中的垃圾收集" src="http://s5.sinaimg.cn/bmiddle/51501580g8169fb66ab44&690">

    二、垃圾收集類型
    年幼代填滿后,一次只針對(duì)該代的收集被執(zhí)行,這樣的收集也被稱作“次收集(minor collection)”。當(dāng)年長(zhǎng)代或永久代被填滿后,一次針對(duì)所有代的完整收集被執(zhí)行,這樣的收集也被稱作“主收集(major collection)”。通常來(lái)說(shuō),在一次主收集過(guò)程中,年幼代首先被收集,收集算法采用當(dāng)前收集器的年幼代收集算法,該算法往往是針對(duì)年幼對(duì)象的行為特征而專門設(shè)計(jì)的;然后是對(duì)年長(zhǎng)代和永久代的收集,收集算法都采用當(dāng)前收集器的年長(zhǎng)代收集算法。對(duì)于給定收集器所具體使用的年幼代和年長(zhǎng)代收集算法,請(qǐng)參考下文。另外,主收集過(guò)程中如果存在壓縮,則每代獨(dú)自進(jìn)行。
    不過(guò),首先收集年幼代的策略在年長(zhǎng)代空閑空間太小時(shí)會(huì)失效,因?yàn)槟觊L(zhǎng)代已無(wú)足夠的空間來(lái)接納所有的可能從年幼代提升過(guò)來(lái)的對(duì)象;在這種情況下,除CMS外的所有收集器都會(huì)放棄原有的年幼代收集算法,轉(zhuǎn)而統(tǒng)一采用年長(zhǎng)代收集算法對(duì)所有代進(jìn)行收集。(CMS收集器之所以例外是因?yàn)樗哪觊L(zhǎng)代算法不能用來(lái)收集年幼代。)

    三、快速分配
    從下文對(duì)垃圾收集器的描述中可以看出,在許多情況下,內(nèi)存中都有大塊的連續(xù)空閑空間用以滿足對(duì)象的分配請(qǐng)求。這種情形下的分配操作使用簡(jiǎn)單的“bump-the-pointer”技術(shù),效率很高。按照這種技術(shù),JVM內(nèi)部維護(hù)一個(gè)指針(allocatedTail),它始終指向先前已分配對(duì)象的尾部,當(dāng)新的對(duì)象分配請(qǐng)求到來(lái)時(shí),只需檢查代中剩余空間(從allocatedTail到代尾geneTail)是否足以容納該對(duì)象,并在“是”的情況下更新allocatedTail指針并初始化對(duì)象。下面的偽代碼具體展示了從連續(xù)內(nèi)存塊中分配對(duì)象時(shí)分配操作的簡(jiǎn)潔性和高效性:
    void * malloc(int n){
    if( geneTail - allocatedTail < n )
    doGarbageCollection();
    void * wasAllocatedTail = allocatedTail;
    allocatedTail += n;
    return wasAllocatedTail;
    }
    對(duì)于多線程應(yīng)用,分配操作必須是線程安全的。如果使用全局鎖為此提供保證,則分配操作必定成為一個(gè)性能瓶頸。基于此,HotSport JVM采用了一種被稱為“線程局部分配緩沖區(qū)”(Thread-Local Allocation Buffers,TLAB)的技術(shù)。該項(xiàng)技術(shù)為每個(gè)線程提供一個(gè)獨(dú)立的分配緩沖區(qū)(伊甸區(qū)的一小部分),借此來(lái)提高分配操作的吞吐量。因?yàn)獒槍?duì)每個(gè)TLAB,只有一個(gè)線程從中分配對(duì)象,故而分配操作可以使用“bump-the-pointer”技術(shù)快速完成,而不必使用任何鎖機(jī)制;只有當(dāng)線程將其已有TLAB填滿并且需要獲取一個(gè)新的TLAB時(shí),同步才是必須的。同時(shí),為了減少TLAB所帶來(lái)的空間消耗,還使用了一些其他技術(shù),例如,分配器能夠把TLAB的平均大小限制在伊甸區(qū)的1%以下。
    “bump-the-pointer”和TLAB技術(shù)的組合保證了分配操作的高效性,類似new Object()這樣的操作在大部分時(shí)間內(nèi)只需要大約10條機(jī)器指令即可完成。

    四、收集方式
    1)串行(serial)和并行(parallel)
    串行和并行是從收集任務(wù)本身如何被完成的角度來(lái)描述收集過(guò)程的。采用串行方式收集時(shí),同一時(shí)間只有一件事情會(huì)發(fā)生。例如,即使有多個(gè)CPU可用,還是只有一個(gè)被用來(lái)執(zhí)行收集任務(wù)。當(dāng)采用并行方式收集時(shí),垃圾收集任務(wù)被分成許多子任務(wù),并且那些子任務(wù)在不同的CPU上被同時(shí)執(zhí)行。同時(shí)操作使收集任務(wù)得以更快地完成,代價(jià)是增加了任務(wù)的復(fù)雜性并可能產(chǎn)生內(nèi)存碎片。2)STW(stop-the-world)和并發(fā)(concurrent)
    STW和并發(fā)是從收集任務(wù)是否影響應(yīng)用程序執(zhí)行的角度來(lái)描述收集過(guò)程的。當(dāng)垃圾收集使用STW方式進(jìn)行時(shí),在收集期間應(yīng)用程序?qū)⒈煌耆珤炱稹W鳛榱硪环N選擇,收集任務(wù)可以采取并發(fā)方式,與應(yīng)用程序一起同時(shí)執(zhí)行。比較典型的情況是,并發(fā)收集器采取并發(fā)方式完成大部分工作,但也可能偶爾地不得不切換到STW方式,以完成一些需要應(yīng)用程序短暫停頓的工作。STW收集比并發(fā)收集更為簡(jiǎn)單,因?yàn)樵谑占陂g堆被凍結(jié)、對(duì)象不會(huì)改變;它的缺點(diǎn)是對(duì)某些應(yīng)用程序來(lái)說(shuō),被暫停過(guò)久是不符合要求的。相對(duì)地,采用并發(fā)方式進(jìn)行垃圾收集時(shí),停頓時(shí)間會(huì)更短,但這也要求收集器必須更加小心,因?yàn)樗诓僮骺赡鼙粦?yīng)用程序同時(shí)更新的對(duì)象。對(duì)并發(fā)收集器來(lái)說(shuō),這會(huì)增加額外開(kāi)銷從而影響性能,也會(huì)對(duì)堆空間產(chǎn)生更大的需求。

    五、串行收集器(serial collector)
    使用串行收集器時(shí),對(duì)年幼代和年長(zhǎng)代的收集都采用串行、STW方式進(jìn)行。也就是說(shuō)收集任務(wù)同時(shí)只使用一個(gè)CPU,而且在收集任務(wù)執(zhí)行期間,應(yīng)用程序的執(zhí)行被中止。
    1)串行收集器如何收集年幼代?
    下圖展示了使用串行收集器對(duì)年幼代進(jìn)行收集時(shí)的操作細(xì)節(jié)。伊甸區(qū)中的活動(dòng)對(duì)象被拷貝到初始為空的生還區(qū)2中;已占用的生還區(qū)1中的活動(dòng)對(duì)象如果仍顯年輕,則同樣被拷貝到生還區(qū)2中,否則被直接拷貝到年長(zhǎng)代;需要注意的是,生還區(qū)2一旦被填滿,則所有尚未被拷貝的活動(dòng)對(duì)象,不論其來(lái)自伊甸區(qū)還是生還區(qū)1,也不論其曾經(jīng)幸免于多少次次收集,統(tǒng)統(tǒng)被拷貝到年長(zhǎng)代。按照定義,在活動(dòng)對(duì)象被拷貝之后,伊甸區(qū)和生還區(qū)1中的對(duì)象就全部成為垃圾對(duì)象,無(wú)須再被檢查。(垃圾對(duì)象在圖中以“X”標(biāo)記,雖然實(shí)際上收集器并不檢查和標(biāo)記這些對(duì)象。) JVM中的垃圾收集" alt="HotSpot JVM中的垃圾收集" src="http://s4.sinaimg.cn/middle/51501580g81cfe5708d93&690"> 收集完成后,伊甸區(qū)和生還區(qū)1變?yōu)榭臻e空間,活動(dòng)對(duì)象保存在生還區(qū)2中。此時(shí),兩個(gè)生還區(qū)的角色已經(jīng)發(fā)生了互換。如下圖:JVM中的垃圾收集" alt="HotSpot JVM中的垃圾收集" src="http://s4.sinaimg.cn/middle/51501580g81d362167ce3&690"> 2)串行收集器如何收集年長(zhǎng)代?
    串行收集器采用標(biāo)記-清理-壓縮算法收集年長(zhǎng)代和永久代。在標(biāo)記階段,收集器遍歷引用樹(shù),找出所有活動(dòng)對(duì)象并打上標(biāo)記;在清理階段,順序掃描代空間中所有對(duì)象(不論死活),計(jì)算出每個(gè)活動(dòng)對(duì)象在代空間中的新位置;在壓縮階段,指向活動(dòng)對(duì)象的所有引用被先期更新后,所有活動(dòng)對(duì)象也被逐個(gè)滑動(dòng)到其新的位置。由于所有活動(dòng)對(duì)象都是按照次序朝代空間頭部移動(dòng)的,因此就在代空間尾部自然形成了一個(gè)單一而連續(xù)的空閑空間。如下圖:JVM中的垃圾收集" alt="HotSpot JVM中的垃圾收集" src="http://s3.sinaimg.cn/middle/51501580g81fd1aa883d2&690">壓縮過(guò)程使基于年長(zhǎng)代或永久代的分配操作可以使用快速的“bump-the-pointer”技術(shù)。
    3)何時(shí)使用串行收集器?
    對(duì)于運(yùn)行在客戶端級(jí)硬件上并且對(duì)停頓時(shí)間沒(méi)有特別要求的大多數(shù)應(yīng)用而言,串行收集器都是首選。按照目前的硬件水平,串行收集器可以高效地管理使用64MB堆空間、最長(zhǎng)停頓時(shí)間不能超過(guò)半秒的很多重要應(yīng)用。
    4)串行收集器的選用
    在J2SE 5.0版本中,對(duì)于非服務(wù)器級(jí)硬件而言,串行收集器作為缺省的垃圾收集器被自動(dòng)選用;對(duì)于其他硬件平臺(tái),則可以通過(guò)命令行選項(xiàng)“-XX:+UseSerialGC”進(jìn)行顯示的選用。

    六、并行收集器(parallel collector)
    目前,許多Java應(yīng)用的運(yùn)行平臺(tái)大都包含很多物理內(nèi)存和多個(gè)CPU。并行收集器,也被稱作吞吐量收集器,被開(kāi)發(fā)出來(lái)的主要目的就是為了充分利用CPU資源,而不是只讓一個(gè)CPU去做垃圾收集而其他CPU卻被閑置。
    1)并行收集器如何收集年幼代?
    和串行收集器相比,并行收集器采用了大致相同的年幼代收集算法,只是執(zhí)行的是其并行版本而已。對(duì)年幼代的收集雖然仍基于拷貝技術(shù)、采用STW方式進(jìn)行,但收集工作是并行展開(kāi)的,使用了多個(gè)CPU,這就降低了垃圾收集開(kāi)銷,從而提高了應(yīng)用程序的吞吐量。下圖展示了并行收集器和串行收集器在執(zhí)行年幼代收集時(shí)到底有何不同:
    JVM中的垃圾收集" alt="HotSpot JVM中的垃圾收集" src="http://s7.sinaimg.cn/middle/51501580g81e435e495a6&690">
    2)并行收集器如何收集年長(zhǎng)代?
    和串行收集器一樣,并行收集器對(duì)年長(zhǎng)代的收集同樣基于標(biāo)記-清理-壓縮算法,同樣采用串行、STW方式進(jìn)行。
    3)何時(shí)使用并行收集器?
    能夠得益于并行收集器的應(yīng)用程序,必定運(yùn)行在多CPU機(jī)器上,并且對(duì)停頓時(shí)間不能有特別的約束。因?yàn)榭赡艹掷m(xù)時(shí)間很長(zhǎng)的年長(zhǎng)代收集雖然稀少,但還是會(huì)發(fā)生的。適于采用并行收集器的典型應(yīng)用包括批處理、記帳、工資單和科學(xué)計(jì)算等等。你可能更傾向于選擇并行壓縮收集器(見(jiàn)下文)而不是并行收集器,因?yàn)榍罢邔?duì)所有代(而不只是年幼代)的收集都采用并行方式進(jìn)行。
    4)并行收集器的選用
    在J2SE 5.0版本中,對(duì)于服務(wù)器級(jí)硬件而言,并行收集器作為缺省的垃圾收集器被自動(dòng)選用;對(duì)于其他硬件平臺(tái),則可以通過(guò)命令行選項(xiàng)“-XX:+UseParallelGC”進(jìn)行顯示的選用。

    七、并行壓縮收集器(parallel compacting collector)
    并行壓縮收集器在J2SE 5.0 U6中引入,它和并行收集器的區(qū)別在于,對(duì)年長(zhǎng)代的收集它使用了全新的算法。注意:并行壓縮收集器終將取代并行收集器。
    1)并行壓縮收集器如何收集年幼代?
    同并行收集器,不再贅述。
    2)并行壓縮收集器如何收集年長(zhǎng)代?
    使用并行壓縮收集器時(shí),對(duì)年長(zhǎng)代和永久代的收集都采用帶滑動(dòng)壓縮的準(zhǔn)并行、STW方式進(jìn)行。為了滿足并行處理的要求,每一個(gè)代空間均被邏輯劃分為諸多定長(zhǎng)區(qū)域(fixed-sized region),每個(gè)區(qū)域的相關(guān)信息保存在收集器維護(hù)的內(nèi)部數(shù)據(jù)結(jié)構(gòu)中。收集過(guò)程被分為標(biāo)記、匯總和壓縮三個(gè)階段進(jìn)行。在標(biāo)記階段,根引用集被劃分給多個(gè)垃圾收集線程,它們同時(shí)運(yùn)行,以并行的方式對(duì)活動(dòng)對(duì)象進(jìn)行追蹤和標(biāo)記;在活動(dòng)對(duì)象被標(biāo)記的同時(shí),該對(duì)象的起始區(qū)域的數(shù)據(jù)也將被同步更新以反映該活動(dòng)對(duì)象的大小和位置信息。
    在匯總階段(summary phase),操作不再基于對(duì)象,而是區(qū)域。考慮到先前收集過(guò)程中的壓縮累積效應(yīng),每一個(gè)代空間中位于左側(cè)的某一部分通常是密集的,主要包含了活動(dòng)對(duì)象。從這樣的密集區(qū)塊中可能回收的空間數(shù)量使得它們并不值得被壓縮。所以匯總階段的首要任務(wù)就是檢查區(qū)域的密集度,從最左邊一個(gè)區(qū)域開(kāi)始,直到找到這樣的一個(gè)區(qū)域,使得在該區(qū)域及其右側(cè)所有區(qū)域中可被回收的空間數(shù)量抵得上對(duì)它們進(jìn)行壓縮的成本。該區(qū)域左側(cè)的所有區(qū)域就被稱為密集前置區(qū)塊,沒(méi)有對(duì)象會(huì)被移入其中。該區(qū)域及其右側(cè)所有區(qū)域會(huì)被壓縮,以消除所有死區(qū)。匯總階段的下一個(gè)任務(wù)就是計(jì)算并保存每個(gè)被壓縮區(qū)域中活動(dòng)數(shù)據(jù)的首字節(jié)在壓縮后的新位置。需要注意的是:匯總階段在目前被實(shí)現(xiàn)為一個(gè)串行階段,這也是“準(zhǔn)”并行方式的由來(lái);并行實(shí)現(xiàn)也是可能的,只是與標(biāo)記和壓縮階段的并行化相比,它對(duì)性能的影響不大。
    在壓縮階段,垃圾收集線程使用匯總數(shù)據(jù)確定需要被填充的區(qū)域,然后它們就可以獨(dú)立地把對(duì)象拷貝到這些區(qū)域中而不再需要額外的同步。這就產(chǎn)生了一個(gè)堆,堆空間的一端塞滿了活動(dòng)對(duì)象,而另一端則是一個(gè)單一而連續(xù)的空閑內(nèi)存塊。
    3)何時(shí)使用并行壓縮收集器?
    和并行收集器一樣,并行壓縮收集器同樣有益于在多CPU機(jī)器上運(yùn)行的應(yīng)用程序。除此之外,年長(zhǎng)代收集的并行化操作方式還減少了停頓時(shí)間,使得并行壓縮收集器比并行收集器更為適合那些有停頓時(shí)間限制的應(yīng)用。不過(guò),對(duì)于運(yùn)行在大型共享主機(jī)(如SunRays)上的應(yīng)用來(lái)說(shuō),并行壓縮收集器也許并不太合適,因?yàn)槿魏螁我粦?yīng)用都不應(yīng)長(zhǎng)時(shí)間獨(dú)占幾個(gè)CPU。在這樣的機(jī)器上,要么考慮通過(guò)命令行選項(xiàng)“-XX:ParallelGCThreads=n”減少垃圾收集線程的數(shù)目,要么考慮選擇一種不同的收集器。
    4)并行壓縮收集器的選用
    并行壓縮收集器只能通過(guò)命令行選項(xiàng)“-XX:+UseParallelOldGC”進(jìn)行顯示的選用。

    八、并發(fā)的標(biāo)記-清理收集器(Concurrent Mark-Sweep(CMS) Collector)
    對(duì)于許多應(yīng)用來(lái)說(shuō),端到端的吞吐量并不象響應(yīng)時(shí)間那么重要。通常來(lái)講,對(duì)年幼代的收集并不會(huì)引起太長(zhǎng)時(shí)間的停頓。但是對(duì)年長(zhǎng)代的收集,雖然不常發(fā)生,卻可能導(dǎo)致停頓時(shí)間過(guò)長(zhǎng)的狀況,在堆空間很大時(shí)尤其明顯。為了解決這個(gè)問(wèn)題,HotSpot JVM包含了一個(gè)名叫“并發(fā)的標(biāo)記-清理(CMS)收集器”的收集器,它也被稱為低延遲收集器。
    1)CMS收集器如何收集年幼代?
    同并行收集器,不再贅述。
    2)CMS收集器如何收集年長(zhǎng)代?
    采用CMS收集器收集年長(zhǎng)代時(shí),大部分收集任務(wù)與應(yīng)用程序并發(fā)執(zhí)行。
    CMS收集器的收集周期始于初始標(biāo)記,它采用串行、STW方式進(jìn)行,用于確定根引用集。隨后進(jìn)入并發(fā)標(biāo)記階段,完成對(duì)所有活動(dòng)對(duì)象的追蹤和標(biāo)記,在JDK6中該階段已開(kāi)始采用并行、并發(fā)方式進(jìn)行。由于在并發(fā)標(biāo)記過(guò)程中應(yīng)用程序正在執(zhí)行并可能更新了一些對(duì)象的引用域,因此并發(fā)標(biāo)記過(guò)程結(jié)束時(shí)并非所有活動(dòng)對(duì)象都已確保被標(biāo)記出來(lái)。為了處理這種情況,應(yīng)用程序再次暫停,收集過(guò)程進(jìn)入再標(biāo)記階段;它采用并行、STW方式進(jìn)行,通過(guò)對(duì)并發(fā)標(biāo)記過(guò)程中被修改對(duì)象的再次訪問(wèn)最終完成整個(gè)標(biāo)記過(guò)程。因?yàn)樵贅?biāo)記階段的停頓時(shí)間往往是最長(zhǎng)的(超過(guò)初始標(biāo)記停頓甚至次收集停頓),因此再標(biāo)記過(guò)程會(huì)盡量采用并行方式進(jìn)行。
    再標(biāo)記階段完成后,所有活動(dòng)對(duì)象都已確保被標(biāo)記,隨后進(jìn)入并發(fā)清理階段,它采用串行、并發(fā)方式進(jìn)行,就地回收所有垃圾對(duì)象。下圖展示了串行的標(biāo)記-清理-壓縮收集器和CMS收集器在收集年長(zhǎng)代時(shí)的區(qū)別: JVM中的垃圾收集" alt="HotSpot JVM中的垃圾收集" src="http://s13.sinaimg.cn/middle/51501580g82676852d74c&690"> 因?yàn)橐恍┤蝿?wù)(例如再標(biāo)記過(guò)程中對(duì)被修改對(duì)象的再次訪問(wèn))增加了收集器的工作量,CMS收集器的總體開(kāi)銷自然會(huì)增大。對(duì)于大多數(shù)試圖減少停頓時(shí)間的收集器來(lái)說(shuō),這是一種典型的折衷。
    CMS收集器是唯一一個(gè)不使用壓縮技術(shù)的收集器。也就是說(shuō),在垃圾對(duì)象所占用的空間被釋放以后,收集器并不把活動(dòng)對(duì)象全部推擠到代空間的某一端去。見(jiàn)下圖:JVM中的垃圾收集" alt="HotSpot JVM中的垃圾收集" src="http://s3.sinaimg.cn/middle/51501580g82716466bed2&690">這種方式節(jié)省了回收時(shí)間,但卻因?yàn)榭臻e空間不再連續(xù),收集器也就不再可能只使用一個(gè)簡(jiǎn)單指針即可指示出可分配給新對(duì)象的下一個(gè)空閑空間的位置,相反,它現(xiàn)在需要使用空閑空間列表。也就是說(shuō),收集器創(chuàng)建并通過(guò)一組列表把內(nèi)存中尚未分配的區(qū)域連接起來(lái),每當(dāng)有對(duì)象需要分配空間時(shí),適當(dāng)?shù)牧斜恚ɑ谒鑳?nèi)存數(shù)量)被搜索,以找到一塊足以放下該對(duì)象的空閑區(qū)域。作為結(jié)果,與使用“bump-the-pointer”技術(shù)時(shí)相比,年長(zhǎng)代中的分配操作變得更加昂貴。同時(shí)這也給年幼代收集帶來(lái)了額外的開(kāi)銷,因?yàn)樵谄涫占^(guò)程中每提升一個(gè)對(duì)象都會(huì)觸發(fā)一次年長(zhǎng)代中的分配操作。
    CMS收集器的另一個(gè)缺點(diǎn)是和其他收集器相比它需要更大的堆空間。一方面,由于在標(biāo)記階段應(yīng)用程序被允許運(yùn)行,它就可能繼續(xù)分配內(nèi)存,從而可能使年長(zhǎng)代空間不斷地增長(zhǎng);另一方面,雖然標(biāo)記階段完成后所有活動(dòng)對(duì)象都已確保被標(biāo)記,但是在標(biāo)記過(guò)程中一些對(duì)象卻可能變?yōu)槔鴮?duì)象,而且直到下次年長(zhǎng)代收集之前它們不會(huì)被回收。這樣的對(duì)象也被稱為游浮垃圾。
    CMS收集器的最后一個(gè)缺點(diǎn)是由于缺乏壓縮它可能引發(fā)碎片化問(wèn)題。為了對(duì)付碎片化,CMS收集器跟蹤對(duì)象的流行尺寸,預(yù)估未來(lái)需求,并為滿足需求還可能分割或合并空閑內(nèi)存塊。
    不象其他收集器,CMS收集器并不是等到年長(zhǎng)代填滿后才啟動(dòng)對(duì)年長(zhǎng)代的收集,而是嘗試盡早啟動(dòng)年長(zhǎng)代收集,以便在年長(zhǎng)代被填滿之前收集過(guò)程可以完成。否則的話,CMS收集器將重新采用在串行和并行收集器中使用的標(biāo)記-清理-壓縮算法,盡管該算法工作于STW方式,也更加耗時(shí)。為避免這種情況的發(fā)生,CMS收集器對(duì)先前收集所耗時(shí)間和代空間充滿所耗時(shí)間進(jìn)行統(tǒng)計(jì),并據(jù)此確定收集啟動(dòng)時(shí)間。另外,當(dāng)年長(zhǎng)代的空間占用率超過(guò)啟動(dòng)占用率(initiating occupancy)時(shí),CMS收集器也將啟動(dòng)一次收集。啟動(dòng)占用率的值可以通過(guò)命令行選項(xiàng)“-XX:CMSInitiatingOccupancyFraction=n”進(jìn)行設(shè)定,其中 n 表示年長(zhǎng)代空間大小的百分比。缺省值為68。
    總的來(lái)說(shuō),與并行收集器相比,CMS收集器(有時(shí)甚至顯著地)減少了年長(zhǎng)代收集的停頓時(shí)間,而代價(jià)是略有增加的年幼代收集的停頓時(shí)間、吞吐量方面的一些損失和額外的堆空間需求。
    3)增量模式
    CMS收集器可以采用讓并發(fā)階段增量完成的模式運(yùn)行。這種模式通過(guò)對(duì)并發(fā)階段的周期性暫停把處理能力交還給應(yīng)用程序,以減少并發(fā)階段持續(xù)時(shí)間過(guò)長(zhǎng)所帶來(lái)的不利影響。收集工作被分成許多小的時(shí)間塊,它們?cè)谀暧状占拈g歇期被調(diào)度。當(dāng)應(yīng)用程序既需要CMS收集器提供的低停頓時(shí)間,又只能在很少的CPU(比如說(shuō)1到2個(gè))上運(yùn)行時(shí),這個(gè)特性就相當(dāng)有用。
    4)何時(shí)使用CMS收集器?
    如果應(yīng)用程序需要更短的垃圾收集停頓時(shí)間并且能夠承擔(dān)在運(yùn)行時(shí)和垃圾收集器共享處理器資源,那么就可以使用CMS收集器。(由于其并發(fā)性,在垃圾收集過(guò)程中CMS收集器將和應(yīng)用程序搶奪CPU周期。)通常來(lái)說(shuō),具有較大的長(zhǎng)壽數(shù)據(jù)集并且運(yùn)行在2個(gè)或多個(gè)CPU上的應(yīng)用程序,更容易受益于CMS收集器的使用。一個(gè)典型的例子就是Web服務(wù)器。對(duì)于任何需要低停頓時(shí)間的應(yīng)用程序來(lái)說(shuō),CMS收集器都值得考慮。對(duì)于年長(zhǎng)代尺寸適中并且運(yùn)行在單一處理器上的交互式應(yīng)用程序來(lái)說(shuō),使用CMS收集器同樣可能取得不錯(cuò)的效果。
    5)CMS收集器的選用
    CMS收集器只能通過(guò)命令行選項(xiàng)“-XX:+UseConcMarkSweepGC”進(jìn)行顯示的選用。如果希望CMS收集器在增量模式下運(yùn)行,還需要通過(guò)命令行選項(xiàng)“-XX:+CMSIncrementalMode”啟用該模式。

    九、收集器、堆尺寸和虛擬機(jī)的自動(dòng)選擇
    在J2SE 5.0中,根據(jù)應(yīng)用程序所運(yùn)行的硬件平臺(tái)和操作系統(tǒng),垃圾收集器、堆尺寸和HotSpot虛擬機(jī)(客戶機(jī)或服務(wù)器)的缺省值被自動(dòng)選定。這些自動(dòng)的選擇不僅減少了對(duì)命令行選項(xiàng)的使用,而且還更好的滿足了不同類型應(yīng)用程序的需要。
    1)服務(wù)器級(jí)硬件(server-class machine,不使用“機(jī)器”這個(gè)詞是因?yàn)樽x起來(lái)太拗口)的定義:
    服務(wù)器級(jí)硬件必須同時(shí)滿足以下兩個(gè)條件:
    ①擁有2個(gè)或以上的物理處理器
    ②擁有2GB或以上的物理內(nèi)存
    該定義適用于所有平臺(tái),32位Windows平臺(tái)除外。
    2)服務(wù)器級(jí)硬件與非服務(wù)器級(jí)硬件下各項(xiàng)缺省值的比較:
    機(jī)器類型 虛擬機(jī) 垃圾收集器 堆尺寸初始值-Xms 堆尺寸最大值-Xmx
    服務(wù)器級(jí)硬件 服務(wù)器版 并行收集器 物理內(nèi)存的1/64,不超過(guò)1GB 物理內(nèi)存的1/4,不超過(guò)1GB
    非服務(wù)器級(jí)硬件 客戶機(jī)版 串行收集器 4MB 64MB
    注意:本節(jié)所涉及的堆尺寸指的是Java堆的大小,包括年幼代和年長(zhǎng)代,但不包括永久代。  

    posted on 2011-10-30 20:47 paulwong 閱讀(346) 評(píng)論(0)  編輯  收藏 所屬分類: 性能優(yōu)化

    主站蜘蛛池模板: 精品国产污污免费网站入口在线| 午夜免费福利小电影| 久草视频在线免费看| AV无码免费永久在线观看| 日本免费一区二区三区最新| 亚洲小说区图片区另类春色| 亚洲成a人片在线观看中文!!!| 猫咪免费人成在线网站| 99re在线这里只有精品免费| 国产免费看插插插视频| 在线观看亚洲一区二区| 黄色免费在线网址| 蜜桃AV无码免费看永久| 亚洲国产成人精品女人久久久 | 日产乱码一卡二卡三免费| 国产亚洲av片在线观看播放| 亚洲va久久久久| 两个人日本免费完整版在线观看1| 91免费资源网站入口| 国产精品亚洲w码日韩中文| 亚洲精品福利你懂| 免费无码又爽又刺激网站直播| 成年人性生活免费视频| 久久精品国产亚洲夜色AV网站| 色噜噜狠狠色综合免费视频| 国产精品永久免费10000| 亚洲乱码国产乱码精品精| 亚洲爆乳AAA无码专区| 精品国产免费人成电影在线观看 | 免费手机在线看片| 成人无码区免费A片视频WWW| 国产精品亚洲一区二区三区在线| 亚洲av无码专区在线电影| 免费无码VA一区二区三区| 亚洲区小说区图片区| 午夜免费福利影院| 亚洲国产成人久久综合碰碰动漫3d| 亚洲AV无码专区在线观看成人| 亚洲黄色免费观看| 亚洲国产精品无码久久一区二区 | 国产免费69成人精品视频|