jvm如何判斷對象是否可以被回收


內容基本來自周志明 深入理解Java虛擬機 第二版 第三章 。這本書還可以,不過好像也沒什么其他中文的關於jvm比較好的書了

jvm要做垃圾回收時,首先要判斷一個對象是否還有可能被使用。那么如何判斷一個對象是否還有可能被用到?

如果我們的程序無法再引用到該對象,那么這個對象就肯定可以被回收,這個狀態稱為不可達。當對象不可達,該對象就可以作為回收對象被垃圾回收器回收。

那么這個可達還是不可達如何判斷呢?

答案就是GC roots ,也就是根對象,如果從一個對象沒有到達根對象的路徑,或者說從根對象開始無法引用到該對象,該對象就是不可達的。

以下三類對象在jvm中作為GC roots,來判斷一個對象是否可以被回收 
(通常來說我們只要知道虛擬機棧和靜態引用就夠了)

  • 虛擬機棧(JVM stack)中引用的對象(准確的說是虛擬機棧中的棧幀(frames)) 
    我們知道,每個方法執行的時候,jvm都會創建一個相應的棧幀(棧幀中包括操作數棧、局部變量表、運行時常量池的引用),棧幀中包含這在方法內部使用的所有對象的引用(當然還有其他的基本類型數據),當方法執行完后,該棧幀會從虛擬機棧中彈出,這樣一來,臨時創建的對象的引用也就不存在了,或者說沒有任何gc roots指向這些臨時對象,這些對象在下一次GC時便會被回收掉

  • 方法區中類靜態屬性引用的對象 
    靜態屬性是該類型(class)的屬性,不單獨屬於任何實例,因此該屬性自然會作為gc roots。只要這個class存在,該引用指向的對象也會一直存在。class 也是會被回收的,在面后說明

  • 本地方法棧(Native Stack)引用的對象

一個class要被回收准確的說應該是卸載,必須同時滿足以下三個條件

  • 堆中不存在該類的任何實例
  • 加載該類的classloader已經被回收
  • 該類的java.lang.Class對象沒有在任何地方被引用,也就是說無法通過反射再帶訪問該類的信息

這篇內容太少了,在說幾句java中的四種引用類型

其實這四類引用的區別就在於GC時是否回收該對象

    • 強引用(Strong) 就是我們平時使用的方式 A a = new A();強引用的對象是不會被回收的
    • 軟引用(Soft) 在jvm要內存溢出(OOM)時,會回收軟引用的對象,釋放更多內存
    • 弱引用(Weak) 在下次GC時,弱引用的對象是一定會被回收的
    • 虛引用(Phantom) 對對象的存在時間沒有任何影響,也無法引用對象實力,唯一的作用就是在該對象被回收時收到一個系統通知


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM