java面試一日一題:java中垃圾回收算法有哪些

  • 2021 年 5 月 14 日
  • 筆記

問題:請講下在java中有哪些垃圾回收算法

分析:該問題主要考察對java中垃圾回收的算法以及使用場景

回答要點:

主要從以下幾點去考慮,

1、GC回收算法有哪些

2、每種算法的使用場景

3、基於垃圾回收算法有哪些垃圾回收器

 

在《java面試一日一題:如何判斷一個對象是否為垃圾對象》中知道了java中判斷一個對象是否存活,是否可被回收使用的是可達性分析算法,找出了可回收的對象,那麼有哪些回收算法可以回收這些對象那

複製算法

複製算法就是從一個地方複製到另外一個地方,針對垃圾回收來說,就是把活着的對象複製到另外一塊內存區域,然後之前的內存區域中的對象便可以被回收。在同等大小內存前提下,複製算法的內存使用率比較低,因為它會把內存分為兩個部分,如下圖

複製算法-回收前

複製算法-回收後

 

標記-清除算法

標記-清除算法,首先是一個標記的過程,也就是標記出哪些對象是垃圾,然後進行清除操作。該算法不需要像複製算法似的,把內存分為兩部分,它可以利用整塊的內存,在內存利用率上是沒有問題的,但是容易產生內存碎片,隨着內存的回收,可能在內存中就不存在整塊的大內存,在分配需要連續空間的大對象(數組)時就會發生OOM。如下圖

標記清除-算法前

標記清除-算法後

從上圖可以看到在使用標記-清除算法後,被標記為垃圾的對象被回收了,釋放了內存空間,但是內存中存在了一個隔一個的空,也就是內存碎片,這時如果要分配一個連續的大空間,可能有無法找到空間的情況,發生OOM。

另外,使用標記-清除算法,在進行內存分配的時候採用的內存分配算法一定是空閑列表法。

標記-整理/壓縮算法

標記-整理/壓縮,是在標記清除的基礎上加了一個內存整理的過程,是為了消除內存碎片的,如下圖

標記-整理前

標記-整理後

從上圖可以看出,使用標記整理算法後內存是規整的,解決了標記-清除算法中內存碎片的問題,但是多了一個內存整理的過程。

分代算法

分代算法,其實不能算是一個垃圾回收的算法,可以理解為一種垃圾回收的方案,即把內存分為不同的塊也即代,每一塊使用不同的垃圾回收算法。現代主流的垃圾回收器都是使用分代的思想,如下圖

上圖即是分代算法的示意圖,把堆區分為新生代和老年代,新生代又分為Eden S0 S1;新生代使用複製算法,老年代使用標記-清除/標記-整理算法。

 

有不當之處,歡迎指正,謝謝