深入了解java虚拟机(JVM) 第六章 垃圾回收算法
一、標記清除算法
? ? ? ? ?標記清除算法顧名思義,就是將需要回收的對象進行標記,然后進行清除。那么這個算法就有標記和清除兩種過程。標記過程主要是通過可達性分析算法進行判斷存活對象,然后遍歷所有的對象來找到需要回收的對象,開始進行清除過程。
這種算法雖然非常的簡單,但是也有很多缺點:1.效率問題,上面我們已經將到了,這個算法在標記的時候需要遍歷GC ROOT的根節點,而且在清除的時候是遍歷了所有對象進行清除,這樣回收的效率就會很低。
? ? 2.空間碎片過多,這個問題可以從上面就可以看出,回收的空間是不連續的,這樣就會出現大量的空間碎片,如果大對象無法分配到足夠的內存,就會提前觸發GC(也可能會出現內存擔保)。
二、復制算法
? ? ? ?為了解決標記清除算法中的效率問題,就有了復制算法,我們通過圖來了解這個算法:
? ? ? ? ?1.將堆分為兩個A、B空間(也可以是多個空間)
2.?所有的對象都創建在A空間
?
?
3.當進行垃圾回收的時候將A中標記的對象全部復制到B空間中,并且將對象排序
?
?
4.然后將A中的空間全部清除,接下來創建的對象,在B空間中創建
?
?5.B空間進行垃圾回收時,則重復第一步開始進行回收
三、jvm中的標記清除算法
? ? ?? 從上圖可以看出這個算法也有一個很大的缺點,就是內存區域的極大浪費,所以在JVM中,對這種算法又進行了一次調優,這種調優方式不是適用于G1垃圾回收器JAVA9開始(默認的垃圾回收器為G1,有的java8默認的垃圾回收器也是G1),這就涉及到一個新的知識:新生代和老年代。
??新生代:新創建的對象都會存放到新生代中(大對象除外)。他的特點是:很快就會被GC回收掉的或者不是特別大的對象。
老年代:在新生代每進行一次垃圾收集后,就會給存活的對象“加1歲”,當年齡達到一定數量的時候就會進入老年代(默認是15)。另外,比較大的對象也會進入老年代(這個會在后面的章節講到),因此,老年代中存放的都是一些生命周期較長的對象或者特別大的對象。
?
jvm中使用標記清除算法,主要用于回收新生代。
1.將堆空間劃分為一個Eden區域(占80%內存空間)和兩個survivor(to和form區域,各站10%),此時空間中創建了一些對象
? ? 2.將Eden中存活的對象放入from區域。
?
?
3.一般來說,Eden區域中存活的對象不是很多,但是如果對象在survivor區域中依然存活,那么開始進行垃圾回收時,將from區域的存活對象放入to區域中,清空to區域和eden區域
?
?4.接下來的回收就用to區域代替from區域,重復第一步進行開始。如果存活對象在進行一定次數的垃圾回收后,依然存活,那么這個對象就進入老年代
? 四、標記整理清除算法
? ? ? ?這種算法主要用于老年代的垃圾回收,這個算法和標記清除類似,只是多了整理這一步驟,這個步驟主要是讓所有存活的對象都向一端移動,然后直接清理掉端邊界以外的內存。
? ?五、分代收集算法
? ? ? ??這種算法將以上算法進行了整合,根據新生代內存回收率搞的內存區域先用標記清除和復制算法。對老年代回收率較低區域的采用標記清除整理算法。
轉載于:https://www.cnblogs.com/daijiting/p/10128822.html
總結
以上是生活随笔為你收集整理的深入了解java虚拟机(JVM) 第六章 垃圾回收算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第十八节20181216
- 下一篇: extend 与 append 的区别