GC的4種算法
複製算法
我們先來看一張原理圖
明確發生的作用域
年輕代中採用的
Minor GC
這種GC算法採用的複製算法
過程分析
當GC開始後 對象只會存在於Eden和From區 而To區是空的 緊接着進行GC Eden中所有存活的對象和From中沒有到閾值的對象被複制到To區 這個時候Eden和From區的對象已經被清空了 這個時候From和To區會交換他們的角色 也就是新的To就是上次的From 新的From就是上次的To區 這樣的目的始終
保證To區是空的
Minor GC會一直進行這樣的過程 直到To區被填滿 會將所有對象移動到老年代
上圖形象理解
Eden中的紅色代表Eden中的存活對象 From區中的紅色代表From區中的存活對象 複製就是把Eden中的紅色對象和From中的紅色對象拿到To去中 然後誰空誰是To 完成了To和From的角色交換 始終保持To區是空的
抽象出一個轉移過程
一旦發生GC 就是將10%的from和80%的eden中存活的對象轉移到to去當中 接下來將90%除to區之外的空間全部釋放
劣勢
適用於存活率不高的情況 如果存活率很高 我們就要把所有的對象都複製一遍
浪費了內存
標記清除
同樣我們先看原理圖
明確發生的作用域
標記清除算法發生在老年代
思想
先將有效指引的對象標記,再清除未標記的對象
優點
相比複製算法來說不浪費內存
缺點
效率低(因爲要遍歷掃描2次),會產生內存碎片(清除後的內存是不連續的)
標記整理(壓縮)
爲了解決Copying算法的缺陷,充分利用內存空間,提出了Mark-Compact算法。該算法標記階段和Mark-Sweep一樣,但是在完成標記之後,它不是直接清理可回收對象,而是將存活對象都向一端移動,然後清理掉端邊界以外的內存。
- 位置:發生在JVM虛擬機的老年代中
- 思想:將標記的對象連續的放到一端,將未標記的對象放到另一端,然後將未標記的對象清除
- 優點:與標記清除算法比,內存是連續的,與複製算法比不浪費內存
- 缺點:效率比複製算法低,需要多維持一個鏈表,用於使倖存的對象連續
引用計數法
給對象添加一個引用計數器,當有一個地方引用它時,計數器值就加1;當引用失效時,計數器就減1;任何時候計數器都爲0的對象就是不可能再被使用的
小總結
-
分代收集算法
一般是把Java堆分爲新生代和老年代,這樣就可以根據各個年代的特點採用最適當的收集算法。在新生代中,每次垃圾收集時都發現有大批對象死去,只有少量存活,那就選用複製算法,只需要付出少量存活對象的複製成本就可以完成收集。而老年代中因爲對象存活率高、沒有額外空間對它進行分配擔保,就必須使用“標記-清理”或“標記-整理”算法來進行回收。
本文參考:https://blog.csdn.net/weixin_41047933/article/details/86009018