1. 程式人生 > >JVM學習--(四)垃圾回收算法

JVM學習--(四)垃圾回收算法

解決 cat 也會 成本高 內存空間 技術分享 減少 圖片 改變

我們都知道java語言與C語言最大的區別就是內存自動回收,那麽JVM是怎麽控制內存回收的,這篇文章將介紹JVM垃圾回收的幾種算法,從而了解內存回收的基本原理。

stop the world

在介紹垃圾回收算法之前,我們需要先了解一個詞“stop the world”,stop the world會在執行某一個垃圾回收算法的時候產生,JVM為了執行垃圾回收,會暫時java應用程序的執行,等垃圾回收完成後,再繼續運行。如果你使用JMeter測試過java程序,你可能會發現在測試過程中,java程序有不規則的停頓現象,其實這就是“stop the world”,停頓的時候JVM是在做垃圾回收。所以盡可能減少stop the world的時間,就是我們優化JVM的主要目標。接下來我們看一下目前有哪些常見垃圾回收的算法。

引用計數法

引用計數法顧名思義,就是對一個對象被引用的次數進行計數,當增加一個引用計數就加1,減少一個引用計數就減1。

技術分享圖片

上圖表示3個Teacher的引用指向堆中的Teacher對象,那麽Teacher對象的引用計數就是3,以此類推Student對象的引用計數就是2。

技術分享圖片

上圖表示Teacher對象的引用減少為2,Student對象的引用減少為0(減少的原因是該引用指向了null,例如teacher3=null),按照引用計數算法,Student對象的內存空間將被回收掉。

引用計數算法原理非常簡單,是最原始的回收算法,但是java中沒有使用這種算法,原因有2。1是頻繁的計數影響性能,2是它無法處理循環引用的問題。

例如Teacher對象中引用了Student對象,Student對象中又引用了Teacher對象,這種情況下,對象將永遠無法被回收。

標記清除

標記清除算法,它是很多垃圾回收算法的基礎,簡單來說有兩個步驟:標記、清除。

標記:遍歷所有的GC Roots,並將從GC Roots可達的對象設置為存活對象;

清除:遍歷堆中的所有對象,將沒有被標記可達的對象清除;

技術分享圖片

註意上圖灰色的對象,因為從GC Root遍歷不到它們(盡管它們本身有引用關系,但從GC Root無法遍歷到它們),因此它們沒有被標記為存活對象,在清除過程中將會被回收。

這裏需要註意的是標記清除算法執行過程中,會產生“stop the world”,讓java程序暫停等待以保證在標記清除的過程中,不會有新的對象產生。為什麽必須暫停java程序呢?舉個例子,如果在標記過程完成後,又新產生了一個對象,而該對象已經錯過了標記期,那麽在接下來的清除流程中,這個新產生的對象因為未被標記,所以將被視為不可達對象而被清除,這樣程序就會出錯,因此標記清除算法在執行時,java程序將被暫停,產生“stop the world”。

接下來我們總結一下標記清除算法:

1、因為涉及大量的內存遍歷工作,所以執行性能較低,這也會導致“stop the world”時間較長,java程序吞吐量降低;

2、我們註意到對象被清除之後,被清除的對象留下內存的空缺位置,造成內存不連續,空間浪費。

接下來我們看一下其他算法能不能改善這些問題?

標記壓縮

標記壓縮算法你可能已經想到了,它就是在標記清除算法的基礎上,增加了壓縮過程。

技術分享圖片

在進行完標記清除之後,對內存空間進行壓縮,節省內存空間,解決了標記清除算法內存不連續的問題。

註意標記壓縮算法也會產生“stop the world”,不能和java程序並發執行。在壓縮過程中一些對象內存地址會發生改變,java程序只能等待壓縮完成後才能繼續。

復制算法

復制算法簡單來說就是把內存一分為二,但只使用其中一份,在垃圾回收時,將正在使用的那份內存中存活的對象復制到另一份空白的內存中,最後將正在使用的內存空間的對象清除,完成垃圾回收。

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

復制算法相對標記壓縮算法來說更簡潔高效,但它的缺點也顯而易見,它不適合用於存活對象多的情況,因為那樣需要復制的對象很多,復制性能較差,所以復制算法往往用於內存空間中新生代的垃圾回收,因為新生代中存活對象較少,復制成本較低。它另外一個缺點是內存空間占用成本高,因為它基於兩份內存空間做對象復制,在非垃圾回收的周期內只用到了一份內存空間,內存利用率較低。

小結

以上我們介紹了常見的垃圾回收算法,這些算法各有各的優缺點,但在JVM中並不是單純的使用特定的算法,而是使用的一種叫垃圾回收器的東西,垃圾回收器可以看做一系列算法的不同組合,在不同的場景使用合適的垃圾回收器,才能起到事半功倍的效果。我們下一篇將介紹垃圾回收器。

JVM學習--(四)垃圾回收算法