乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      深入理解JVM之垃圾回收詳解

       jnstyle 2016-04-15

      一、 垃圾收集的意義

      C++中,對(duì)象所占的內(nèi)存在程序結(jié)束運(yùn)行之前一直被占用,在明確釋放之前不能分配給其它對(duì)象;而在Java中,當(dāng)沒(méi)有對(duì)象引用指向原先分配給某個(gè)對(duì)象的內(nèi)存時(shí),該內(nèi)存便成為垃圾。垃圾收集器釋放丟棄對(duì)象所占的內(nèi)存空間,內(nèi)存會(huì)出現(xiàn)碎片。碎片是分配給對(duì)象的內(nèi)存塊之間的空閑內(nèi)存洞。碎片整理將所占用的堆內(nèi)存移到堆的一端,JVM將整理出的內(nèi)存分配給新的對(duì)象。

      垃圾收集能自動(dòng)釋放內(nèi)存空間,減輕編程的負(fù)擔(dān)。這使Java虛擬機(jī)具有一些優(yōu)點(diǎn)。首先,它能使編程效率提高。在沒(méi)有垃圾收集機(jī)制的時(shí)候,可能要花許多時(shí)間來(lái)解決一個(gè)難懂的存儲(chǔ)器問(wèn)題。在用Java語(yǔ)言編程的時(shí)候,靠垃圾收集機(jī)制可大大縮短時(shí)間。其次是它保護(hù)程序的完整性, 垃圾收集是Java語(yǔ)言安全性策略的一個(gè)重要部份。垃圾收集的一個(gè)潛在的缺點(diǎn)是它的開銷影響程序性能。Java虛擬機(jī)必須追蹤運(yùn)行程序中有用的對(duì)象,而且最終釋放沒(méi)用的對(duì)象。這一個(gè)過(guò)程需要花費(fèi)處理器的時(shí)間。其次垃圾收集算法的不完備性,早先采用的某些垃圾收集算法就不能保證100%收集到所有的廢棄內(nèi)存。當(dāng)然隨著垃圾收集算法的不斷改進(jìn)以及軟硬件運(yùn)行效率的不斷提升,這些問(wèn)題都可以迎刃而解。一般來(lái)說(shuō),Java開發(fā)人員可以不重視JVM中堆內(nèi)存的分配和垃圾處理收集,但是,充分理解Java的這一特性可以讓我們更有效地利用資源。同時(shí)要注意finalize方法是Java的缺省機(jī)制,有時(shí)為確保對(duì)象資源的明確釋放,可以編寫自己的finalize方法。

      二、對(duì)象的判定

      Java堆中存放著幾乎所有的對(duì)象實(shí)例,垃圾收集器對(duì)堆中的對(duì)象進(jìn)行回收前,要先確定這些對(duì)象是否還有用,判定對(duì)象是否為垃圾對(duì)象有如下算法:

      1、 引用計(jì)數(shù)法

      引用計(jì)數(shù)是垃圾收集器中的早期策略。在這種方法中,堆中每個(gè)對(duì)象(不是引用)都有一個(gè)引用計(jì)數(shù)。對(duì)于一個(gè)對(duì)象 A,只要有任何一個(gè)對(duì)象引用了 A,則A 的引用計(jì)數(shù)器就加 1,當(dāng)引用失效時(shí),引用計(jì)數(shù)器就減 1。只要對(duì)象 A 的引用計(jì)數(shù)器的值為 0,則對(duì)象 A就不可能再被使用。

      引用計(jì)數(shù)法實(shí)現(xiàn)簡(jiǎn)單,判定效率也很高。但是這個(gè)算法有明顯的缺陷,對(duì)于循環(huán)引用的情況下,循環(huán)引用的對(duì)象就不會(huì)被回收。如A=B,B=A,此時(shí),對(duì)象 A 和對(duì)象B 的引用計(jì)數(shù)器都不為 0。但是在系統(tǒng)中卻不存在任何第 3 個(gè)對(duì)象引用了 A 或 B。也就是說(shuō),A 和 B 是應(yīng)該被回收的垃圾對(duì)象,但由于垃圾對(duì)象間相互引用,從而使垃圾回收器無(wú)法識(shí)別,引起內(nèi)存泄漏。

      2、 根搜索算法

      這種算法的基本思路是通過(guò)一系列名為“GC Roots”的對(duì)象作為起始點(diǎn),從這些節(jié)點(diǎn)開始向下搜索,搜索所走過(guò)的路徑稱為引用鏈,當(dāng)一個(gè)對(duì)象到GC Roots沒(méi)有任何引用鏈相連時(shí),就證明此對(duì)象是不可用的。在Java語(yǔ)言里,可作為GC Roots的對(duì)象包括下面幾種:

      • 虛擬機(jī)棧(棧幀中的本地變量表)中引用的對(duì)象。
      • 方法區(qū)中的類靜態(tài)屬性引用的對(duì)象。
      • 方法區(qū)中的常量引用的對(duì)象。
      • 本地方法棧中JNI(Native方法)的引用對(duì)象。

      三、引用的類型

      無(wú)論是通過(guò)引用計(jì)數(shù)算法判斷對(duì)象的引用數(shù)量,還是通過(guò)根搜索算法判斷對(duì)象的引用鏈?zhǔn)欠窨蛇_(dá),判斷對(duì)象是否存活都與“引用有關(guān)”。一般的引用類型分為強(qiáng)引用( Strong Reference)、軟引用( Soft Reference)、弱引用( Weak Reference)、虛引用( Phantom Reference)四種,這四種引用強(qiáng)度依次逐漸減弱。

      1、強(qiáng)引用就是指在程序代碼之中普遍存在的,類似“Objectobj = new Object”這類的引用,只要強(qiáng)引用還存在,垃圾收集器永遠(yuǎn)不會(huì)回收掉被引用的對(duì)象。當(dāng)內(nèi)存空間不足,Java虛擬機(jī)寧愿拋出OutOfMemoryError錯(cuò)誤,使程序異常終止,也不會(huì)靠隨意回收具有強(qiáng)引用的對(duì)象來(lái)解決內(nèi)存不足的問(wèn)題。如果不使用時(shí),可以賦值obj=null,顯示的設(shè)置ob為null,則gc認(rèn)為該對(duì)象不存在引用,這時(shí)候就可以回收此對(duì)象。

      強(qiáng)引用在實(shí)際應(yīng)用中非常常見(jiàn),集合類中的clear方法就用到了強(qiáng)引用,下面看一下hashmap中clear方法的源代碼

      transient Node<K,V> table; public void clear { Node<K,V> tab; modCount++; if ((tab = table) != null && size > 0) { size = 0; for (int i = 0; i < tab.length; ++i) tab[i] = null; } }

      在HashMap類中定義了一個(gè)table數(shù)組,在調(diào)用clear方法清空數(shù)組時(shí)可以看到為每個(gè)數(shù)組內(nèi)容賦值為null。不同于table=null,強(qiáng)引用仍然存在,避免在其他方法用到數(shù)組時(shí)重新的內(nèi)存分配。使用如clear方法中釋放內(nèi)存的方法對(duì)數(shù)組中存放的引用類型特別適用,這樣就可以及時(shí)釋放內(nèi)存。

      2、軟引用用來(lái)描述一些還有用,但并非必需的對(duì)象。對(duì)于軟引用關(guān)聯(lián)著的對(duì)象,如果內(nèi)存充足,則垃圾回收器不會(huì)回收該對(duì)象,如果內(nèi)存不夠了,就會(huì)回收這些對(duì)象的內(nèi)存。在JDK 1.2之后,提供了SoftReference類來(lái)實(shí)現(xiàn)軟引用。軟引用可用來(lái)實(shí)現(xiàn)內(nèi)存敏感的高速緩存。軟引用可以和一個(gè)引用隊(duì)列(ReferenceQueue)聯(lián)合使用,如果軟引用所引用的對(duì)象被垃圾回收器回收,Java虛擬機(jī)就會(huì)把這個(gè)軟引用加入到與之關(guān)聯(lián)的引用隊(duì)列中。

      軟引用主要應(yīng)用于內(nèi)存敏感的高速緩存,在android系統(tǒng)中經(jīng)常使用到。一般情況下,Android應(yīng)用會(huì)用到大量的默認(rèn)圖片,這些圖片很多地方會(huì)用到。如果每次都去讀取圖片,由于讀取文件需要硬件操作,速度較慢,會(huì)導(dǎo)致性能較低。所以我們考慮將圖片緩存起來(lái),需要的時(shí)候直接從內(nèi)存中讀取。但是,由于圖片占用內(nèi)存空間比較大,緩存很多圖片需要很多的內(nèi)存,就可能比較容易發(fā)生OutOfMemory異常。這時(shí),我們可以考慮使用軟引用技術(shù)來(lái)避免這個(gè)問(wèn)題發(fā)生。SoftReference可以解決oom的問(wèn)題,每一個(gè)對(duì)象通過(guò)軟引用進(jìn)行實(shí)例化,這個(gè)對(duì)象就以cache的形式保存起來(lái),當(dāng)再次調(diào)用這個(gè)對(duì)象時(shí),那么直接通過(guò)軟引用中的get方法,就可以得到對(duì)象中中的資源數(shù)據(jù),這樣就沒(méi)必要再次進(jìn)行讀取了,直接從cache中就可以讀取得到,當(dāng)內(nèi)存將要發(fā)生OOM的時(shí)候,GC會(huì)迅速把所有的軟引用清除,防止oom發(fā)生。

      下面看一段簡(jiǎn)單的代碼:

      public class BitMapManager { private Map<String, SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>; //保存Bitmap的軟引用到HashMap public void saveBitmapToCache(String path) { // 強(qiáng)引用的Bitmap對(duì)象 Bitmap bitmap = BitmapFactory.decodeFile(path); // 軟引用的Bitmap對(duì)象 SoftReference<Bitmap> softBitmap = new SoftReference<Bitmap>(bitmap); // 添加該對(duì)象到Map中使其緩存 imageCache.put(path, softBitmap); // 使用完后手動(dòng)將位圖對(duì)象置null bitmap = null; } public Bitmap getBitmapByPath(String path) { // 從緩存中取軟引用的Bitmap對(duì)象 SoftReference<Bitmap> softBitmap = imageCache.get(path); // 判斷是否存在軟引用 if (softBitmap == null) { return null; } // 取出Bitmap對(duì)象,如果由于內(nèi)存不足Bitmap被回收,將取得空 Bitmap bitmap = softBitmap.get; return bitmap; } }

      3、弱引用也是用來(lái)描述非必需對(duì)象的,當(dāng)JVM進(jìn)行垃圾回收時(shí),無(wú)論內(nèi)存是否充足,都會(huì)回收被弱引用關(guān)聯(lián)的對(duì)象。在jdk1.2后,用WeakReference類來(lái)實(shí)現(xiàn)弱引用。弱引用與軟引用的區(qū)別在于:只具有弱引用的對(duì)象擁有更短暫的生命周期。下面看一個(gè)簡(jiǎn)單例子:

      import java.lang.ref.WeakReference; public class WeakReferenceTest { public static void main(String args) { WeakReference<String> sr ; sr= new WeakReference<String>(new String("弱引用")); System.out.println(sr.get);//輸出弱引用 System.gc; //通知JVM的gc進(jìn)行垃圾回收 System.out.println(sr.get);//輸出null //如果存在強(qiáng)引用同時(shí)與之關(guān)聯(lián),則進(jìn)行垃圾回收時(shí)也不會(huì)回收該對(duì)象 String str = new String (new String("弱引用")); sr = new WeakReference<String>(str); System.gc; //通知JVM的gc進(jìn)行垃圾回收 System.out.println(sr.get); //輸出弱引用 } }4、虛引用和前面的軟引用、弱引用不同,它并不影響對(duì)象的生命周期。在java中用java.lang.ref.PhantomReference類表示。如果一個(gè)對(duì)象與虛引用關(guān)聯(lián),則跟沒(méi)有引用與之關(guān)聯(lián)一樣,在任何時(shí)候都可能被垃圾回收器回收。要注意的是,虛引用必須和引用隊(duì)列關(guān)聯(lián)使用,當(dāng)垃圾回收器準(zhǔn)備回收一個(gè)對(duì)象時(shí),如果發(fā)現(xiàn)它還有虛引用,就會(huì)把這個(gè)虛引用加入到與之關(guān)聯(lián)的引用隊(duì)列中。程序可以通過(guò)判斷引用隊(duì)列中是否已經(jīng)加入了虛引用,來(lái)了解被引用的對(duì)象是否將要被垃圾回收。如果程序發(fā)現(xiàn)某個(gè)虛引用已經(jīng)被加入到引用隊(duì)列,那么就可以在所引用的對(duì)象的內(nèi)存被回收之前采取必要的行動(dòng)。下面看一個(gè)簡(jiǎn)單的例子:import java.lang.ref.PhantomReference; import java.lang.ref.ReferenceQueue; public class PhantomReferenceTest { public static void main(String args) { ReferenceQueue<String> queue = new ReferenceQueue<String>; PhantomReference<String> pr = new PhantomReference<String>(new String("虛引用"), queue); System.out.println(pr.get);//輸出null } }

      四、垃圾收集算法

      1、標(biāo)記-清除算法(Mark-Sweep)

      標(biāo)記-清除算法分為標(biāo)記和清除兩個(gè)階段:首先標(biāo)記出所有需要回收的對(duì)象,在標(biāo)記完成后統(tǒng)一回收所有被標(biāo)記的對(duì)象,標(biāo)記過(guò)程其實(shí)就是根搜索算法判斷對(duì)象是否存活。該算法主要不足有兩個(gè):一個(gè)是效率問(wèn)題,標(biāo)記和清除兩個(gè)過(guò)程的效率都不高;另一個(gè)是空間問(wèn)題,標(biāo)記清除之后會(huì)產(chǎn)生大量不連續(xù)的內(nèi)存碎片,空間碎片太多可能會(huì)導(dǎo)致以后在程序運(yùn)行過(guò)程中需要分配較大的對(duì)象時(shí),無(wú)法找到足夠的連續(xù)內(nèi)存而不得不提前觸發(fā)另一次垃圾收集動(dòng)作。標(biāo)記-清除算法的執(zhí)行過(guò)程如下圖所示:

      圖一、“標(biāo)記-清除”算法示意圖

      2、復(fù)制算法(Coping)

      復(fù)制算法是把內(nèi)存分成大小相等的兩塊,每次使用其中一塊,當(dāng)垃圾回收的時(shí)候,把存活的對(duì)象復(fù)制到另一塊上,然后把這塊內(nèi)存整個(gè)清理掉。這樣使得每次都是對(duì)整個(gè)半?yún)^(qū)進(jìn)行內(nèi)存回收,內(nèi)存分配時(shí)就不用考慮內(nèi)存碎片等復(fù)雜情況,實(shí)現(xiàn)簡(jiǎn)單,運(yùn)行高效。這種方法適用于短生存期的對(duì)象,持續(xù)復(fù)制長(zhǎng)生存期的對(duì)象則導(dǎo)致效率降低。復(fù)制算法的執(zhí)行過(guò)程如下圖所示:

      圖二、復(fù)制算法示意圖

      3、標(biāo)記-整理算法(Mark-Compact)

      復(fù)制算法在對(duì)象存活率較高時(shí)就要進(jìn)行較多的復(fù)制操作,效率將會(huì)降低。老年代更常見(jiàn)的情況是大部分對(duì)象都是存活對(duì)象。如果依然使用復(fù)制算法,由于存活的對(duì)象較多,復(fù)制的成本也將很高。標(biāo)記-整理算法是一種老年代的回收算法,該算法與標(biāo)記-清除算法的標(biāo)記過(guò)程一樣,但是之后不是直接對(duì)可回收對(duì)象進(jìn)行清理,而是讓所有存活的對(duì)象都向一端移動(dòng),然后直接清理掉端邊界以外的內(nèi)存。這種方法既避免了碎片的產(chǎn)生,又不需要兩塊相同的內(nèi)存空間,其性價(jià)比比較高。該算法示意圖如下圖所示:

      圖三、“標(biāo)記-整理”算法示意圖

      4、分代收集算法

      根據(jù)垃圾回收對(duì)象的特性,不同階段最優(yōu)的方式是使用合適的算法用于本階段的垃圾回收,分代算法即是基于這種思想,它將內(nèi)存區(qū)間根據(jù)對(duì)象的特點(diǎn)分成幾塊,根據(jù)每塊內(nèi)存區(qū)間的特點(diǎn),使用不同的回收算法,以提高垃圾回收的效率。一般把java堆分為新生代和老年代,新生代采用復(fù)制算法,老年代采用標(biāo)記-整理算法。

      五、垃圾收集器

      垃圾收集算法是內(nèi)存回收的理論基礎(chǔ),而垃圾收集器就是內(nèi)存回收的具體實(shí)現(xiàn)。下面介紹一下HotSpot(JDK 7)虛擬機(jī)提供的幾種垃圾收集器,用戶可以根據(jù)自己的需求組合出各個(gè)年代使用的收集器。HotSpot的虛擬機(jī)的垃圾收集器如下圖所示:

      圖四、 HotSpot虛擬機(jī)的垃圾收集器

      1、Serial收集器

      這個(gè)收集器是一個(gè)單線程收集器,使用復(fù)制收集算法,收集時(shí)會(huì)暫停所有工作線程,直到收集結(jié)束,虛擬機(jī)運(yùn)行在Client模式時(shí)的默認(rèn)新生代收集器。優(yōu)點(diǎn)是:簡(jiǎn)單高效(與其他收集器的單線程相比),對(duì)于限定單個(gè)CPU的環(huán)境來(lái)說(shuō),Serial收集器沒(méi)有現(xiàn)成交互的開銷,做垃圾收集可以獲得最高的單線程收集效率。如下圖:

      圖五、Serial/SerialOld收集器運(yùn)行示意圖

      2、ParNew收集器

      ParNew收集器其實(shí)就是Serial收集器的多線程版本,除了使用多條線程進(jìn)行垃圾收集之外,其余行為包括算法、STW、對(duì)象分配規(guī)則、回收策略等都與Serial收集器一樣。ParNew收集器是許多運(yùn)行在server模式下的虛擬機(jī)中首選的新生代收集器,一個(gè)重要原因是在除了serial收集器外,目前只有它能與CMS收集器配合使用。ParNew收集器在單CPU環(huán)境中不比Serial效果好,甚至可能更差,兩個(gè)CPU也不一定跑的過(guò),但隨著CPU數(shù)量的增加,性能會(huì)逐步增加。ParNew收集器的工作過(guò)程如下:

      圖六、ParNew/SerialOld收集器運(yùn)行示意圖

      3、Parallel Scavenge收集器

      ParallelScavenge收集器是一個(gè)新生代收集器,它是使用復(fù)制算法的并行多線程的收集器。

      ParallelScavenge的特點(diǎn)是它的關(guān)注點(diǎn)與其他收集器不同,CMS等收集器的關(guān)注點(diǎn)盡可能地縮短垃圾收集時(shí)用戶線程的停頓時(shí)間,而Parallel Scavenge收集器的目標(biāo)則是達(dá)到一個(gè)可控制的吞吐量(Throughput)。所謂吞吐量就是CPU用于運(yùn)行用戶代碼時(shí)間與CPU總消耗時(shí)間的比值。吞吐量=運(yùn)行用戶代碼時(shí)間/運(yùn)行用戶代碼時(shí)間+垃圾收集時(shí)間。

      高吞吐量和停頓時(shí)間短的策略相比,主要強(qiáng)調(diào)高效率地利用CPU時(shí)間,任務(wù)更快完成,適用于后臺(tái)運(yùn)算而不需要太多交互的任務(wù);而后者強(qiáng)調(diào)用戶交互體驗(yàn)。

      4、Serial Old收集器

      單線程收集器,是Serial收集器老年代版本,使用“標(biāo)記-整理”算法,主要用在client模式下,如果在Server模式下,它主要有兩大用途:一種用途是在JDK1.5以及之前的版本中與Parallel Scavenge收集器搭配使用;另一用途是作為CMS收集器的后備預(yù)案,在并發(fā)手機(jī)發(fā)生CMF時(shí)使用。

      5、Parallel Old收集器

      Parallel Old是ParallelScavenge收集器的老年代版本,使用多線程和“標(biāo)記-整理”算法。Parallel Old收集器的工作過(guò)程如下圖:

      圖七、Parallel Scavenge/Parallel Old收集器運(yùn)行示意圖

      6、CMS收集器

      CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時(shí)間為目標(biāo)的收集器。CMS收集器是基于“標(biāo)記-清除”算法實(shí)現(xiàn)的,整個(gè)收集過(guò)程大致分為4個(gè)步驟:

      (1)初始標(biāo)記(CMS initial mark):標(biāo)記GC Roots能直接關(guān)聯(lián)到的對(duì)象,速度很快。

      (2)并發(fā)標(biāo)記(CMS concurrent mark):進(jìn)行GC ROOTS根搜索算法階段,會(huì)判定對(duì)象是否存活。

      (3)重新標(biāo)記(CMS remark):修正并發(fā)標(biāo)記期間因用戶程序繼續(xù)運(yùn)行而導(dǎo)致標(biāo)記發(fā)生改變的那一部分對(duì)象的標(biāo)記記錄。

      其中初始標(biāo)記和重新標(biāo)記兩個(gè)階段仍然需要Stop-The-World,整個(gè)過(guò)程中耗時(shí)最長(zhǎng)的并發(fā)標(biāo)記和并發(fā)清除過(guò)程中收集器都可以和用戶線程一起工作。所以整體來(lái)說(shuō),CMS收集器的內(nèi)存回收過(guò)程是與用戶線程一起并發(fā)執(zhí)行的。

      CMS收集器的優(yōu)點(diǎn):并發(fā)收集、低停頓,但是CMS還遠(yuǎn)遠(yuǎn)達(dá)不到完美,器主要有三個(gè)顯著缺點(diǎn):

      (1)CMS收集器對(duì)CPU資源非常敏感。在并發(fā)階段,雖然不會(huì)導(dǎo)致用戶線程停頓,但是會(huì)占用CPU資源而導(dǎo)致引用程序變慢,總吞吐量下降。CMS默認(rèn)啟動(dòng)的回收線程數(shù)是:(CPU數(shù)量+3) / 4。

      (2)CMS收集器無(wú)法處理浮動(dòng)垃圾,可能出現(xiàn)“Concurrent Mode Failure“,失敗后而導(dǎo)致另一次Full GC的產(chǎn)生。

      (3)最后一個(gè)缺點(diǎn),CMS是基于“標(biāo)記-清除”算法實(shí)現(xiàn)的收集器,使用“標(biāo)記-清除”算法收集后,會(huì)產(chǎn)生大量碎片??臻g碎片太多時(shí),將會(huì)給對(duì)象分配帶來(lái)很多麻煩,比如說(shuō)大對(duì)象,內(nèi)存空間找不到連續(xù)的空間來(lái)分配不得不提前觸發(fā)一次Full GC。

      圖八、CMS收集器運(yùn)行示意圖

      7、G1收集器

      G1收集器是一款面向服務(wù)端應(yīng)用的垃圾收集器,用于替換CMS收集器。與其他GC收集器相比,G1具有以下幾個(gè)特點(diǎn):

      (1)并行與并發(fā):充分利用多CPU、多核環(huán)境下的硬件優(yōu)勢(shì),使用多個(gè)CPU來(lái)縮短Stop-The-World停頓時(shí)間,在收集過(guò)程中用并發(fā)的方式讓Java線程繼續(xù)執(zhí)行。

      (2)分代收集:仍然有分代的概念,不需要其他收集器配合能獨(dú)立管理整個(gè)GC堆,能夠采用不同的方式去處理新創(chuàng)建的對(duì)象和已經(jīng)存活了一段時(shí)間、熬過(guò)多次GC的就對(duì)象以獲得更好的收集效果。

      (3)空間整合:G1從整體看,是基于“標(biāo)記-整理”算法實(shí)現(xiàn)的,從局部(兩個(gè)Region之間)看是基于“復(fù)制”算法的。在運(yùn)行期間不會(huì)產(chǎn)生內(nèi)存碎片,有利于程序長(zhǎng)時(shí)間運(yùn)行分配大對(duì)象時(shí)不會(huì)因?yàn)闊o(wú)法找到連續(xù)內(nèi)存而提前出發(fā)下一次GC。

      (4)可預(yù)測(cè)的停頓:G1除了追求低停頓外,還能建立可預(yù)測(cè)的停頓時(shí)間模型。

      G1收集器運(yùn)作大致可以分為以下幾個(gè)步驟:

      (1)初始標(biāo)記:只標(biāo)記GC Roots能直接關(guān)聯(lián)到的對(duì)象,并且修改TAMS(Next Topat Mark Start)值,讓下一階段用戶程序并發(fā)運(yùn)行時(shí),能在正確可用的Region中創(chuàng)建新對(duì)象。此階段需要停頓用戶線程。

      (2)并發(fā)標(biāo)記:從GC Roots開始對(duì)堆中對(duì)象進(jìn)行可達(dá)性分析,找出存活對(duì)象;耗時(shí)較長(zhǎng),可與用戶線程并發(fā)執(zhí)行。

      (3)最終標(biāo)記:修正在并發(fā)標(biāo)記期間有變動(dòng)的標(biāo)記記錄,這階段需要停頓線程,可以并行執(zhí)行。

      (4)篩選回收:對(duì)各個(gè)Region的回收價(jià)值和成本進(jìn)行排序,根據(jù)用戶期望的GC停頓時(shí)間制定回收計(jì)劃,進(jìn)行垃圾回收。

      圖九、G1收集器運(yùn)行示意圖

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多