===G1垃圾回收器是如何划分堆空間的呢?
G1垃圾回收器將內存分成一個個小塊區域,這些小塊區域的大小可以是1M,2M,4M,8M等等,並且這些小塊區域可以是eden,survivor,old,以及humongous區域。其中humongous用來存大對象,如果一個對象超過某塊空間的1/2的時候就會被認為是大對象來進行處理。

===G1如何進行對象空間分配的呢?
對於一個線程來說它有自己的eden區域,如果不夠用就會使用公共的eden區域,再不夠就使用老年代
===G1垃圾回收器有哪些GC的算法呢?
G1提供了三種GC模式,Young GC,old GC和Mixed GC,兩種都是Stop The World(STW)的。
1.youngGC,eden區域空間耗盡了就進行的垃圾回收。
eden優先到survivor,不夠就到老年代,survivor也會轉移到新的survivor或者到老年代中去。目的是直到eden區域清空為止。
===young GC中如何標記被老年代引用的新生代呢?如何避免掃描所有的老年代?
因為有些老年代引用到新生代的對象,為了避免掃描整個老年代,所以使用卡表記錄。
---CMS中在老年代有個RS(Remember set記錄集合)數據區域記錄指向新生代的引用:所以老年代中有個RS區域記錄了老年代對新生代的引用,這樣直接掃描這個RS區域就可以了不需要掃描整個老年代。
---G1中在每個分區使用卡表數組來進行記錄Card Table。卡表記錄這個分區的每個位置的使用情況,如果被引用了就標記成0,同時也在RS中進行記錄。
我的理解就是老年代有個RS哈希表,鍵是某塊新生代起始地址,value就是卡表,卡表里面記錄哪塊區域被引用,這樣直接就掃這個RS和卡表就能夠知道老年代引用了新生代什么對象了。
2.MIX GC混合式GC
當老年代的空間降低到一定程度了就觸發Mix Gc。
過程很像CMS垃圾回收。主要分為兩個步驟:全局並發標記和拷貝存活對象
---initial mark: 初始標記過程,整個過程STW,標記了從GC Root可達的對象
---concurrent marking: 並發標記過程,整個過程gc collector線程與應用線程可以並行執行,標記出GC Root可達對象衍生出去的存活對象,並收集各個Region的存活對象信息
---remark: 最終標記過程,整個過程STW,標記出那些在並發標記過程中遺漏的,或者內部引用發生變化的對象
---clean up: 垃圾清除過程,如果發現一個Region中沒有存活對象,則把該Region加入到空閑列表中
---並發掃描過程中的三色標記算法
有黑色(根對象或者掃描過的對象),灰色(正在掃描對象),和白色(未掃描對象)三種。

---並發過程中可能出現的對象丟失問題如何解決呢?如何去標記被修改了的對象呢?

在並發修改的時候可能導致一個對象丟失的情況。比如以上C對象就被丟失掉了。如何解決呢?
CMS的解決方式:如果一個白對象被黑對象引用,直接就變成灰色。
G1中使用的方式是:開始標記的時候生成快照(STAB,snapshot-at-the-beginning),並發標記的時候某個對象被修改了就直接插入寫屏障write barrier。
3.老年代GC
如果對象內存分配速度過快,mixed gc來不及回收,導致老年代被填滿,就會觸發 一次full gc,G1的full gc算法就是單線程執行的serial old gc,會導致異常長時間的暫停時間,需要進行不斷的調優,盡可能的避免full gc.
===調優參數設置
最大暫停時間MaxGCPauseMillis
如果MaxGCPauseMillis設置的過小,那么GC就會頻繁,吞吐量就會下降。如果MaxGCPauseMillis設置的過大,應用程序暫停時間就會變長。G1的默認暫停時間是200毫秒,我們可以從這里入手,調整合適的時間。