首頁 >Java >java教程 >JAVA虛擬機器(JVM)詳細介紹(三)-垃圾收集機制

JAVA虛擬機器(JVM)詳細介紹(三)-垃圾收集機制

王林
王林轉載
2019-08-24 14:21:572684瀏覽

在上一篇我們說過,自動記憶體管理分為兩部分:給物件分配記憶體和回收分配給物件的記憶體。這篇我們說說後者,也就是回收分配給物件的記憶體。回收記憶體要用到垃圾收集機制,英文名兒是GC(Garbage Collection)。

在本部分我們要解決以下幾個問題:

1、哪些記憶體需要回收?

2、什麼時候回收?

3、如何回收?

哪些記憶體需要回收?

堆和方法區的記憶體需要回收,其餘的不需要回收。
因為只有堆和方法區是執行緒共享的,其餘的是與執行緒「同生共死」的,執行緒結束,記憶體自然就跟著回收了,所以不用管它們。

什麼時候回收?

(1)在堆裡面:

當物件「死了」的時候就要對其進行記憶體回收了。啥叫對象死了?就是沒有地方引用它了,它無用了。那要怎麼判斷它是否死了呢?

有兩種方法:

引用計數演算法

為物件新增一個引用計數器,每當有一個地方引用它時,計數器的值就1,當引用失效時,計數器的值就-1,當計數器的值為0時,代表此物件已不被引用,也就是「可以死了」。

但這有一個弊端,就是循環引用的問題。就像下圖,堆裡的兩個物件即使無用了也沒辦法對其進行回收,因為它們互相引用著,計數器的值至少為1。

JAVA虛擬機器(JVM)詳細介紹(三)-垃圾收集機制

可達性分析

所有產生的物件都是稱為「GC Roots」的根的子樹。從GC Roots開始向下搜索,搜索所經過的路徑稱為引用鏈。當一個物件到GC Roots沒有任何引用鏈可以到達時,就稱這個物件是不可達的,也就是可以被GC回收了。這個是Java中採用較多的方式。

就像下圖中的堆中未被引用的對象,就可以對其進行回收。

JAVA虛擬機器(JVM)詳細介紹(三)-垃圾收集機制

怎麼判斷一個物件是否還存在著引用? java中的引用分為4種:

強引用:Object o=new Object(),只要強引用存在,GC就永遠不會回收被引用的物件。

軟引用:描述一些還有用但非必要的物件。當系統即將發生記憶體溢出了,就會回收。

弱引用:只要進行GC,就會對其進行回收。

虛引用:這是最弱的一種引用關係,無法透過虛引用來取得一個物件實例。它的作用是:能在這個物件被收集器回收時收到一個系統通知。

(2)在方法區裡面:


#我們知道,方法區裡儲存的是已被虛擬機器載入的類別訊息,常數,靜態變數,即時編譯器編譯後的程式碼等資料。所以我們在方法區裡面進行垃圾回收,回收的是一些廢棄的常數和無用的類別。

怎麼判斷一個常數是否被廢棄了?

看引用計數就可以,如果沒有物件來引用該常數,則表示此常數被廢棄了,也就可以回收了。

怎麼判斷一個類別是無用的類別?

有3種情況:

a、該類別所有的實例都已經被回收。

b、載入該類別的ClassLoader已經被回收。

c、該類別對應的java.lang.Class物件沒有任何地方被引用,無法在任何地方透過反射存取該類別的方法。

如何回收

有4種演算法作為理論:
• 標記-清除演算法
• 複製演算法
• 標記-整理演算法
• 分代收集演算法

有5種收集器作為實作:

JAVA虛擬機器(JVM)詳細介紹(三)-垃圾收集機制

#後記

#記憶體溢位:系統無法再分配出你需要的空間。例如在堆中無法再給新生的物件分配記憶體了,在棧裡棧滿了無法再讓新棧幀進棧了。

記憶體洩漏:記憶體被物件佔用不還,就叫記憶體外洩。

以上便是關於JVM中垃圾回收機制的詳細講解,更多相關問題請訪問PHP中文網:JAVA影片教學

#

以上是JAVA虛擬機器(JVM)詳細介紹(三)-垃圾收集機制的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除