魅藍 65W GaN 快速充電器正式開售:支援 USB-C 和 USB-A 雙口輸出,109 元
一、垃圾收集演算法
① 分代收集理論
核心:根據物件存活週期的不同將記憶體分為幾塊。一般將java堆分為新生代和老年代,這樣我們就可以根據各個年代的特點選擇不同的垃圾收集演算法。
比如在新生代,每次收集都會有大量的物件死去,所以可以選擇複製演算法,只需要付出少量物件的複製就可以完成每次垃圾收集。
而老年代的物件存活機率比較高,而且沒有額外的空間對它分配擔保,所以我們必須選擇“標記-清除”或“標記-整理”演算法進行垃圾收集。注意,“標記-清除”或“標記-整理”演算法會比複製演算法慢10倍以上。
② 複製演算法
核心:為了解決效率問題,引出了複製演算法。它將記憶體分為大小相同的兩塊空間,每次只使用一塊。當這一塊的記憶體使用完後,將存活物件複製到另外一塊記憶體,然後再把當前使用空間一次清理掉。
優點:效率高。 缺點:浪費記憶體空間,記憶體使用率低。
③ 標記-清除演算法
核心:分為兩個階段“標記”和“清除”。 將存活物件標記出來,然後對未標記物件進行清除。或者反過來,對未存活物件標記,然後進行清除。
缺點: 1.如果標記的物件太多,那麼回收效率不高 2. 記憶體碎片化,會產生大量的記憶體碎片。
④ 標記-整理演算法
核心:區別於標記清除演算法的地方在於,標記完物件後,會先將物件移動到一端(向同一端移動),然後對分界線另一端進行清除。
二、垃圾收集器(優化垃圾收集器最核心的點就是為了減少STW時間)
本文著重講解CMS垃圾收集器和G1垃圾收集器
如果說收集演算法是記憶體回收的方法論,那麼垃圾收集器就是記憶體回收的具體實現
① Serial
單執行緒收集器(新生代採用複製演算法,老年代採用標記-整理演算法)
② Paraller Scavenge
Serial收集器的多執行緒版本。預設的收集執行緒數跟cpu核數相同,當然也可以用引數(-XX:ParallelGCThreads)指定收集執行緒數,但是一般不推薦修改。Parallel Scavenge收集器關注點是吞吐量(高效率的利用CPU)。
CMS等垃圾收集器的關注點更多的是使用者執行緒的停頓時間(提高使用者體驗)。所謂吞吐量就是CPU中用於執行使用者程式碼的時間與CPU總消耗時間的比值。
③ ParNew
ParNew收集器其實跟Parallel收集器很類似,區別主要在於它可以和CMS收集器配合使用。
新生代採用複製演算法,老年代採用標記-整理演算法。
④ CMS(Concurrent Mark Sweep)
<1> 是一種以獲取最短回收停頓時間為目標的收集器。非常符合使用在注重使用者體驗的系統中,第一次實現了讓垃圾收集執行緒和使用者執行緒(基本上)同時工作。
從名字中的Mark Sweep這兩個詞可以看出,CMS收集器是一種 “標記-清除”演算法實現的。它的整個回收過程大概如下:
1. 初始標記:暫停所有的其他執行緒(STW),並記錄下所有 GC Roots(區域性變量表中引用的物件、本地方法引用的物件、方法區中靜態屬性引用的物件、方法區中靜態常量池中引用的物件)直接能引用的物件,速度很快。
2. 併發標記:併發標記階段就是從GC Roots的直接關聯物件開始遍歷整個物件圖的過程, 這個過程耗時較長但是不需要停頓使用者執行緒, 可以與垃圾收集執行緒一起併發執行。因為使用者程式繼續執行,可能會有導致已經標記過的物件狀態發生改變。
3. 重新標記:修正併發標記期間因為使用者程式繼續執行而導致標記產生變動的那一部分物件的標記記錄,這個階段的停頓時間一般會比初始標記階段的時間稍長,遠遠比並發標記階段時間短。主要用到三色標記裡的增量更新演算法(見下面詳解)做重新標記
4. 併發清理:開啟使用者執行緒,同時GC執行緒開始對未標記的區域做清掃。這個階段如果有新增物件會被標記為黑色不做任何處理(見下面三色標記演算法詳解)。
5. 併發重置:重置本次GC過程中的標記資料。
<2> 優點:併發收集、低停頓。
<3> 缺點:① 對CPU資源敏感(會和服務搶資源)。 ② 無法處理浮動垃圾(在併發標記和併發清理階段又產生垃圾,這種浮動垃圾只能等到下一次gc再清理了) ③ 它使用的回收演算法-“標記-清除”演算法會導致收集結束時會有大量空間碎片產生,當然通過引數-
XX:+UseCMSCompactAtFullCollection可以讓jvm在執行完標記清除後再做整理 ④ 執行過程中的不確定性,會存在上一次垃圾回收還沒執行完,然後垃圾回收又被觸發的情況,特別是在並發標記和併發清理階段會出現,一邊回收,系統一邊執行,
也許沒回收完就再次觸發full gc,也就是"concurrentmode failure",此時會進入stop the world,用serial old垃圾收集器來回收。
未完待續。。。(下班了,明天接著寫,哈哈。。。)