JVM的垃圾回收算法詳解,不看實在是太虧了!

前言

今天同學在課前演講,大致講了一下java虛擬機,講的很快也很淺,反正聽的迷迷糊糊的,自己下來從新進行查找資料進行整理學習,先將JVM裏面的垃圾回收機制中算法進行歸攏,整理如下,如有錯誤或不足請留言或私信告知,定會改正!

垃圾回收機制圖

JVM的垃圾回收算法詳解,不看實在是太虧了!

垃圾對象判定標準

JVM的GC工作主要針對的對象是堆內存,在做GC工作之前,首先要判定堆內存中的對象實例是否爲垃圾,通常使用以下兩種算法來定義

1.引用計數算法

java在運行時,當有一個地方引用該對象實例,會將這個對象實例加1,引用失效時就減1,jvm在掃描內存時,發現引用計數值爲0的則是垃圾對象,計數值大於0的則爲活躍對象。

目前垃圾回收算法,沒有采用引用計數算法,原因是在對象互相引用的情況下,無法判定兩者是否爲垃圾對象。

2.根搜索算法

根搜索算法是以“GC ROOTS”爲起始點往下搜索,所有經過的對象合併起來稱爲引用鏈,在這引用鏈裏,沒有的對象稱爲垃圾對象,(實際上jvm還做了一個篩選動作,判定當前對象是否執行finalize()方法,如果不需要執行才判定爲垃圾對象,這裏不做介紹),在引用鏈裏的是活躍對象。那什麼樣的對象才能稱爲“GC ROOTS”呢?以下四種可以

  • 虛擬機棧(棧幀中的本地變量表)中引用的對象。
  • 方法區中的類靜態屬性引用的對象。
  • 方法區中的常量引用的對象。
  • 本地方法棧中 JNI(Native 方法)的引用對象。

垃圾回收算法

1. 標記-清除(Mark-Sweep)

JVM的垃圾回收算法詳解,不看實在是太虧了!
JVM會掃描所有的對象實例,通過根搜索算法,將活躍對象進行標記,jvm再一次掃描所有對象,將未標記的對象進行清除,只有清除動作,不作任何的處理,這樣導致的結果會存在很多的內存碎片。

2. 複製(copying)

JVM的垃圾回收算法詳解,不看實在是太虧了!
JVM掃描所有對象,通過根搜索算法標記被引用的對象,之後會申請新的內存空間,將標記的對象複製到新的內存空間裏,存活的對象複製完,會清空原來的內存空間,將新的內存最爲JVM的對象存儲空間。這樣雖然解決了內存內存碎片問題,但是如果對象很多,重新申請新的內存空間會很大,在內存不足的場景下,會對JVM運行造成很大的影響

3. 標記-整理(Mark-compact)

JVM的垃圾回收算法詳解,不看實在是太虧了!
標記整理實際上是在標記清除算法上的優化,執行完標記清除全過程之後,再一次對內存進行整理,將所有存活對象統一向一端移動,這樣解決了內存碎片問題。

4. 分代回收

JVM的垃圾回收算法詳解,不看實在是太虧了!
目前JVM常用回收算法就是分代回收,年輕代以複製算法爲主,老年代以標記整理算法爲主。原因是年輕代對象比較多,每次垃圾回收都有很多的垃圾對象回收,而且要儘可能快的減少生命週期短的對象,存活的對象較少,這時候複製算法比較適合,只要將有標記的對象複製到另一個內存區域,其餘全部清除,並且複製的數量較少,效率較高;而老年代是年輕代篩選出來的對象,被標記比較高,需要刪除的對象比較少,顯然採用標記整理效率較高。

結束語

由於個人能力問題,暫時只能整理出目前這些知識,希望能對大家有幫助,關於JVM的具體內容,在下一定會盡快更新,盡請期待!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章