【Android 内存优化】垃圾回收算法 ( 分代收集算法 | Serial 收集器 | ParNew 收集器 | Parallel Scavenge 收集器 | CMS 并发标记清除收集器 )
文章目錄
- 一、 分代收集算法
- 二、 垃圾回收器 / 收集器 ( GC )
- 三、 串行收集器 ( Serial )
- 四、 ParNew 收集器
- 五、 Parallel Scavenge 收集器
- 六、 CMS ( Concurrent Mark Sweep ) 并發標記清除收集器 ( 重點 )
一、 分代收集算法
1. 分代收集算法 : 每個對象的生命周期是不同的 , 某些對象如 Application 整個應用聲明周期都存活 , 某些方法的局部變量對象 , 方法結束后 , 該局部對象就可以被回收了 , 不同聲明周期的對象使用不同的垃圾回收算法 ;
2. Java 虛擬機的堆內存分區 :
- 年輕代 ( Yong Generation )
- 老年代 ( Old Generation )
- 持久代 ( Permanent Generation )
3. 年輕代內存區域 :
① 年輕代內存分為三塊 :
- Eden 區域
- From 區域
- To 區域
② 內存運行機制 : 新創建的對象 , 放在年輕代內存塊中 , 開始時放在 Eden 區域 , 當 Eden 區域存滿后 , 會將存活的對象轉移到 From 區域 和 To 區域 ;
4. 老年代內存區域 :
① 對象晉升 : 對象每經過一次 GC 垃圾回收 , 其年齡就會加 111 ; 當年齡到達虛擬機設置的閾值之后 , 就會被放入老年代內存塊中 ;
② 存放對象 : 老年代存放由年輕代晉升上來的對象 , 這是活得時間比較長的對象 ;
5. 持久代內存區域 : 主要存放類加載器 ( ClassLoader ) 加載的 Class , 常量池 , 等對象 ;
二、 垃圾回收器 / 收集器 ( GC )
1. GC 垃圾回收器 . 收集器 : 在 GC 中實現垃圾回收算法
- 年輕代內存區域的垃圾回收器 : Minor GC
- 老年代內存區域的垃圾回收器 : Major GC
- 整個內存區域的垃圾回收器 : Full GC
注意持久代內存區域的內存不回收 ;
年輕代內存區域與老年代內存區域的垃圾回收機制不同 ;
2. 年輕代又叫新生代 , 新生代內存區域的的垃圾回收器 :
- Serial
- ParNew
- Parallel Scavenge
3. 老年代內存區域的垃圾回收器 :
- CMS
- Serial Old ( MSC )
- Parallel Old
三、 串行收集器 ( Serial )
串行收集器 ( Serial ) : 新生代內存回收使用該回收機制 ;
① 運行內存區域 : Serial 串行垃圾回收器 在 年輕代 內存區域中收集要回收的內存 ;
② 垃圾回收算法 : 復制算法 ;
③ 運行機制 : 垃圾回收線程運行時 , 暫停用戶線程 ;
④ 最基本 GC : Serial 串行垃圾回收器 , 這是最基本的垃圾回收器 , 老版本的 Java 虛擬機使用的就是這種垃圾回收器 ;
⑤ 特點 : 其工作時 , 是單線程 , 串行的 ;
⑥ 單線程執行 : 該垃圾回收器 , 需要暫停所有線程 , 使用單個線程處理回收多個線程的內存回收工作 ;
⑦ 暫停線程 : 執行垃圾回收時 , 必須暫停工作線程 , 直到垃圾收集結束后 , 才能繪制執行 ;
⑧ 安全點 : 停止工作線程的位置是 安全點 , 需要保存該位置的程序執行信息 ;
⑨ 優勢 : 不需要處理多線程交互問題 ;
年輕代 , 復制算法 , 單線程 GC , 暫停用戶線程
四、 ParNew 收集器
ParNew 收集器 :
① 運行區域 : ParNew 垃圾回收器 在 年輕代 內存區域中收集要回收的內存 ;
② 垃圾回收算法 : 復制算法 ;
③ 運行機制 : 垃圾回收線程運行時 , 暫停用戶線程 ;
④ 多線程執行 : 該垃圾回收器 多線程運行 , 消耗時間要比 Serial 串行垃圾回收器要短 ;
⑤ 與 Serial 垃圾回收器對比 : 該 GC 是并行的 , 是 Serial 垃圾回收器的多線程版本 ;
年輕代 , 復制算法 , 多線程 GC , 暫停用戶線程
五、 Parallel Scavenge 收集器
Parallel Scavenge 收集器 :
① 運行區域 : Parallel 垃圾回收器在 年輕代 內存區域中收集要回收的內存 ;
② 垃圾回收算法 : 復制算法 ;
③ 關注吞吐量 : Parallel 垃圾回收器 與 ParNew 垃圾回收器 區別是 , Parallel 垃圾回收器更關注吞吐量 ;
④ 吞吐量概念 : 吞吐量是 CPU 運行正常代碼時間與總的消耗時間之間的比值 , CPU 運行的總時間是 程序運行時間 與 GC 垃圾收集的時間之和 ;
⑤ 吞吐量示例 : CPU 總共運行 100 秒 , 程序運行 95 秒 , 垃圾回收器運行 5 秒 , 那么吞吐量就是 95100=0.95\dfrac{95}{100} = 0.9510095?=0.95 ;
年輕代 , 復制算法 , 多線程 GC , 暫停用戶線程 ( 關注吞吐量 )
六、 CMS ( Concurrent Mark Sweep ) 并發標記清除收集器 ( 重點 )
1. CMS 垃圾回收器 : 全稱 Concurrent Mark Sweep , 并發標記清除收集器 ;
① 運行區域 : CMS 垃圾回收器在 老年代 內存區域中收集要回收的內存 ;
② 垃圾回收算法 : 標記-清除算法 , 會產生很多內存碎片 ;
2. 短暫停頓 : 在 GC 線程運行時 , 用戶線程僅做最短的停頓 , 在停頓過程中主要用于標記內存 ;
由于其停頓時間是各個 GC 算法中最短 , 該并發標記清除收集器又叫 并發低延遲收集器 ;
3. CMS 收集器工作流程 ( 重點 ) : 要標記 333 次后 , 才可以執行清除操作 , 共 444 步驟 ;
① 初始標記 : 標記與 GC Roots 有引用鏈的對象 ; 該操作速度快 , 該步驟需要暫停用戶線程 ;
② 并發標記 : GC Roots 追蹤 , 從初始標記結果集合中標記出存活對象 , 不能保證所有的存活對象都被標記 ; 該步驟與應用程序并發執行 ;
③ 重新標記 : 上一步并發標記 GC 線程與用戶程序并發期間的標記有部分變化 , 修正這部分標記信息 , 之后暫停用戶線程 , 開始標記 ; 該暫停操作要比初始標記步驟暫停時間長 ;
④ 并發清除 : 回收所有 GC Roots 不可達對象 ;
上述四個步驟中 , 并發標記 , 并發清除 , 用時最長 , 但這兩個與用戶線程并發執行 , 因此可以看做該 CMS 垃圾收集器與用戶線程是并發執行的 ;
4. CMS 收集器缺點 :
① CPU 性能消耗 : 多開線程 , 意味著 CPU 性能消耗多 ;
② 內存碎片 : 使用 標記-清除算法 , 會造成很多內存碎片 , 嚴重的話導致 OOM ;
③ 浮動垃圾 : 由于 GC 線程 與用戶線程并發 造成的 , 在 GC 運行過程中產生的用戶線程垃圾 , 需要等待下一次 GC 清理 , 這些垃圾就是浮動垃圾 ;
5 . Android 垃圾收集器 :
Android 中使用的是 CMS 垃圾回收器 , 會產生內存碎片 ;
Android 中內存抖動產生 OOM , 就是因為使用的是 CMS 垃圾回收器 ( 收集器 ) ;
Android 之所以采用標記-清除算法進行垃圾回收 , 是因為這種算法效率很高 , 性能對于嵌入式小型設備來說 , 非常重要 ; 大型服務器可以采用一些復雜的垃圾回收算法 , 如標記-壓縮算法 , 該算法開銷要高于標記-清除算法 ;
老年代 , 標記-清除算法 , 多線程 GC , 與用戶線程并發 / 暫停
總結
以上是生活随笔為你收集整理的【Android 内存优化】垃圾回收算法 ( 分代收集算法 | Serial 收集器 | ParNew 收集器 | Parallel Scavenge 收集器 | CMS 并发标记清除收集器 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 内存优化】垃圾回收算法
- 下一篇: 【Android 内存优化】内存抖动 (