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