JVM垃圾回收與調優

首先,第一個問題:什麼是垃圾?

我們說當一個對象,沒有任何引用指向它的時候,那這個對象就是垃圾。

那麼JVM是怎麼知道這個對象已經沒有引用指向它了呢?也就是說JVM是怎麼找到垃圾的?

目前來說有兩種算法:reference count(引用計數)、Root Searching(根可達)

reference count(引用計數)

在對象的頭信息中記了一個數,每當有一個引用指向了這個對象,就加1。引用失效時,就減1。當計數值爲0的時候,說明這個對象變成了垃圾,需要被回收。

但是引用計數這種方式不能解決循環引用的問題

這裏有A、B、C三個對象循環引用,導致他們的引用計數無法爲0,所以不能被回收。

Root Searching(根可達)

從gcroot(根對象)不斷往下搜索,凡是能找到的都是有用的對象,找不到的就是垃圾。

哪些對象可作爲GCroot?JVM stacks,native method stack,run-time constant pool,static references in method area,Clazz

我們可以簡單理解爲main方法中可以訪問到的對象可作爲根對象。

垃圾回收算法

找到垃圾後,有3種算法可以用於清理垃圾:Mark-Sweep(標記清除)、copying(拷貝)、Mark-Compact(標記壓縮)

  • Mark-Sweep(標記清除)

先標記出需要回收的對象,標記完成後再回收所有被標記的對象。這種算法的缺陷在於容易產生大量不連續的內存碎片。在分配較大對象的時候,無法找到足夠大的連續內存。同時標記和清除的效率也不高。

  • copying(拷貝)

copying就是把內存一分爲二,每次只使用其中一塊,垃圾回收時,只需找到還存活的對象,將它們複製到另一塊內存中,再將已使用的這一整塊內存直接清理掉。這種算法效率比較高,但缺點是浪費空間。

  • Mark-Compact(標記壓縮)

類似於硬盤整理碎片,將存活對象都壓縮到最前端,清理掉邊界外碎片。這種算法效率很低。

內存分區分代模型

整個內存分爲年輕代和老年代兩部分,年輕代中按照 8:1:1分成三部分:eden、survivor1,survivor2

 

 

 

 

 

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