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

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

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

    Garbage First介紹

    本文摘自《構建高性能的大型分布式Java應用》一書,Garbage First簡稱G1,它的目標是要做到盡量減少GC所導致的應用暫停的時間,讓應用達到準實時的效果,同時保持JVM堆空間的利用率,將作為CMS的替代者在JDK 7中閃亮登場,其最大的特色在于允許指定在某個時間段內GC所導致的應用暫停的時間最大為多少,例如在100秒內最多允許GC導致的應用暫停時間為1秒,這個特性對于準實時響應的系統而言非常的吸引人,這樣就再也不用擔心系統突然會暫停個兩三秒了。

    G1要做到這樣的效果,也是有前提的,一方面是硬件環境的要求,必須是多核的CPU以及較大的內存(從規范來看,512M以上就滿足條件了),另外一方面是需要接受吞吐量的稍微降低,對于實時性要求高的系統而言,這點應該是可以接受的。

    為了能夠達到這樣的效果,G1在原有的各種GC策略上進行了吸收和改進,在G1中可以看到增量收集器和CMS的影子,但它不僅僅是吸收原有GC策略的優點,并在此基礎上做出了很多的改進,簡單來說,G1吸收了增量GC以及CMS的精髓,將整個jvm Heap劃分為多個固定大小的region,掃描時采用Snapshot-at-the-beginning的并發marking算法(具體在后面內容詳細解釋)對整個heap中的region進行mark,回收時根據region中活躍對象的bytes進行排序,首先回收活躍對象bytes小以及回收耗時短(預估出來的時間)的region,回收的方法為將此region中的活躍對象復制到另外的region中,根據指定的GC所能占用的時間來估算能回收多少region,這點和以前版本的Full GC時得處理整個heap非常不同,這樣就做到了能夠盡量短時間的暫停應用,又能回收內存,由于這種策略在回收時首先回收的是垃圾對象所占空間最多的region,因此稱為Garbage First

    看完上面對于G1策略的簡短描述,并不能清楚的掌握G1,在繼續詳細看G1的步驟之前,必須先明白G1對于JVM Heap的改造,這些對于習慣了劃分為new generation、old generation的大家來說都有不少的新意。

    G1Heap劃分為多個固定大小的region,這也是G1能夠實現控制GC導致的應用暫停時間的前提,region之間的對象引用通過remembered set來維護,每個region都有一個remembered setremembered set中包含了引用當前region中對象的region的對象的pointer,由于同時應用也會造成這些region中對象的引用關系不斷的發生改變,G1采用了Card Table來用于應用通知region修改remembered setsCard Table由多個512字節的Card構成,這些CardCard Table中以1個字節來標識,每個應用的線程都有一個關聯的remembered set log,用于緩存和順序化線程運行時造成的對于card的修改,另外,還有一個全局的filled RS buffers,當應用線程執行時修改了card后,如果造成的改變僅為同一region中的對象之間的關聯,則不記錄remembered set log,如造成的改變為跨region中的對象的關聯,則記錄到線程的remembered set log,如線程的remembered set log滿了,則放入全局的filled RS buffers中,線程自身則重新創建一個新的remembered set log,remembered set本身也是一個由一堆cards構成的哈希表。

    盡管G1Heap劃分為了多個region,但其默認采用的仍然是分代的方式,只是僅簡單的劃分為了年輕代(young)和非年輕代,這也是由于G1仍然堅信大多數新創建的對象都是不需要長的生命周期的,對于應用新創建的對象,G1將其放入標識為youngregion中,對于這些region,并不記錄remembered set logs,掃描時只需掃描活躍的對象,G1在分代的方式上還可更細的劃分為:fully youngpartially young,fully young方式暫停的時候僅處理young regionspartially同樣處理所有的young regions,但它還會根據允許的GC的暫停時間來決定是否要加入其他的非young regions,G1是運行到fully-young方式還是partially young方式,外部是不能決定的,在啟動時,G1采用的為fully-young方式,當G1完成一次Concurrent Marking后,則切換為partially young方式,隨后G1跟蹤每次回收的效率,如果回收fully-young中的regions已經可以滿足內存需要的話,那么就切換回fully young方式,但當heap size的大小接近滿的情況下,G1會切換到partially young方式,以保證能提供足夠的內存空間給應用使用。

    除了分代方式的劃分外,G1還支持另外一種pure G1的方式,也就是不進行代的劃分,pure方式和分代方式的具體不同在下面的具體執行步驟中進行描述。

    掌握了這些概念后,繼續來看G1的具體執行步驟:

    1.         Initial Marking

    G1對于每個region都保存了兩個標識用的bitmap,一個為previous marking bitmap,一個為next marking bitmap,bitmap中包含了一個bit的地址信息來指向對象的起始點。

    開始Initial Marking之前,首先并發的清空next marking bitmap,然后停止所有應用線程,并掃描標識出每個regionroot可直接訪問到的對象,將regiontop的值放入next top at mark startTAMS)中,之后恢復所有應用線程。

    觸發這個步驟執行的條件為:

    l  G1定義了一個JVM Heap大小的百分比的閥值,稱為h,另外還有一個H,H的值為(1-h)*Heap Size,目前這個h的值是固定的,后續G1也許會將其改為動態的,根據jvm的運行情況來動態的調整,在分代方式下,G1還定義了一個u以及soft limit,soft limit的值為H-u*Heap Size,當Heap中使用的內存超過了soft limit值時,就會在一次clean up執行完畢后在應用允許的GC暫停時間范圍內盡快的執行此步驟;

    l  pure方式下,G1markingclean up組成一個環,以便clean up能充分的使用marking的信息,當clean up開始回收時,首先回收能夠帶來最多內存空間的regions,當經過多次的clean up,回收到沒多少空間的regions時,G1重新初始化一個新的markingclean up構成的環。

    2.         Concurrent Marking

    按照之前Initial Marking掃描到的對象進行遍歷,以識別這些對象的下層對象的活躍狀態,對于在此期間應用線程并發修改的對象的以來關系則記錄到remembered set logs中,新創建的對象則放入比top值更高的地址區間中,這些新創建的對象默認狀態即為活躍的,同時修改top值。

    3.         Final Marking Pause

    當應用線程的remembered set logs未滿時,是不會放入filled RS buffers中的,在這樣的情況下,這些remebered set logs中記錄的card的修改就會被更新了,因此需要這一步,這一步要做的就是把應用線程中存在的remembered set logs的內容進行處理,并相應的修改remembered sets,這一步需要暫停應用,并行的運行。

    4.         Live Data Counting and Cleanup

    值得注意的是,在G1中,并不是說Final Marking Pause執行完了,就肯定執行Cleanup這步的,由于這步需要暫停應用,G1為了能夠達到準實時的要求,需要根據用戶指定的最大的GC造成的暫停時間來合理的規劃什么時候執行Cleanup,另外還有幾種情況也是會觸發這個步驟的執行的:

    l  G1采用的是復制方法來進行收集,必須保證每次的”to space”的空間都是夠的,因此G1采取的策略是當已經使用的內存空間達到了H時,就執行Cleanup這個步驟;

    l  對于full-youngpartially-young的分代模式的G1而言,則還有情況會觸發Cleanup的執行,full-young模式下,G1根據應用可接受的暫停時間、回收young regions需要消耗的時間來估算出一個yound regions的數量值,當JVM中分配對象的young regions的數量達到此值時,Cleanup就會執行;partially-young模式下,則會盡量頻繁的在應用可接受的暫停時間范圍內執行Cleanup,并最大限度的去執行non-young regionsCleanup

    這一步中GC線程并行的掃描所有region,計算每個region中低于next TAMS值中marked data的大小,然后根據應用所期望的GC的短延時以及G1對于region回收所需的耗時的預估,排序region,將其中活躍的對象復制到其他region中。

     

    G1為了能夠盡量的做到準實時的響應,例如估算暫停時間的算法、對于經常被引用的對象的特殊處理等,G1為了能夠讓GC既能夠充分的回收內存,又能夠盡量少的導致應用的暫停,可謂費盡心思,從G1的論文中的性能評測來看效果也是不錯的,不過如果G1能允許開發人員在編寫代碼時指定哪些對象是不用mark的就更完美了,這對于有巨大緩存的應用而言,會有很大的幫助,G1將JDK 6 Update 14 beta發布。

    posted on 2009-03-11 22:18 BlueDavy 閱讀(12560) 評論(4)  編輯  收藏 所屬分類: Java

    評論

    # re: Garbage First介紹 2009-03-14 13:37 phpxer

    Mark  回復  更多評論   

    # re: Garbage First介紹 2009-04-01 12:14 中國兄弟連

    給你踩踩哈!  回復  更多評論   

    # re: Garbage First介紹 2013-03-04 23:52 呵樂貓

    學習了。  回復  更多評論   

    # re: Garbage First介紹 2016-03-01 17:47 mvilplss

    學習啦  回復  更多評論   

    公告

     









    feedsky
    抓蝦
    google reader
    鮮果

    導航

    <2009年3月>
    22232425262728
    1234567
    891011121314
    15161718192021
    22232425262728
    2930311234

    統計

    隨筆分類

    隨筆檔案

    文章檔案

    Blogger's

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 欧美三级在线电影免费| 成人免费大片免费观看网站| 成人免费视频网址| 亚洲丰满熟女一区二区v| 日韩在线播放全免费| 亚洲狠狠久久综合一区77777| 国产免费无码一区二区| 亚洲综合色自拍一区| 成人免费一区二区三区 | 免费在线观看的网站| 亚洲毛片免费观看| 一级特黄aa毛片免费观看| 911精品国产亚洲日本美国韩国| 免费不卡在线观看AV| 亚洲AV日韩AV永久无码绿巨人| 午夜精品一区二区三区免费视频| 久久亚洲日韩精品一区二区三区| 777爽死你无码免费看一二区| 亚洲精品无码久久久久久久| 无码人妻久久一区二区三区免费丨 | 亚洲国产精品免费在线观看| 亚洲婷婷在线视频| 好吊妞998视频免费观看在线| 亚洲AV电影天堂男人的天堂| 亚洲va中文字幕无码| 嫩草影院在线播放www免费观看| 久久亚洲美女精品国产精品| 国产成人免费爽爽爽视频 | 亚洲香蕉在线观看| 国产一级高清视频免费看| 香蕉视频在线免费看| 亚洲一区免费观看| 日韩精品免费电影| 国内精品免费久久影院| 亚洲国产美女福利直播秀一区二区| 全免费A级毛片免费看网站| fc2成年免费共享视频网站| 91在线亚洲精品专区| 国产男女猛烈无遮挡免费网站| 黄桃AV无码免费一区二区三区 | 亚洲av无码专区国产不乱码|