深入理解Java虛擬機讀書筆記-垃圾回收

垃圾回收器執(zhí)行垃圾回收主要做三個事情
1、哪些內(nèi)存需要回收
2、什么時候回收
3、如何回收

  • 哪些內(nèi)存需要回收
    1.引用計數(shù)器法:一個對象有一個引用指向他引用計數(shù)器就加一;引用失效時就減一。為零時,就認為可以被回收。但是這里存在一個問題就是對象的相互引用的時候,導(dǎo)致對象無法回收。
    2.可達性分析:通過一系列的GC Roots來作為引用鏈的起點,如果沒有任何的一個引用鏈相連的話,被視為可回收的對象
    3.png

可以作為GC Roots的對象包括以下幾種:

  • 虛擬機棧中引用的對象

  • 方法區(qū)中靜態(tài)變量引用的對象

  • 方法區(qū)中常量引用的對象

  • JNI引用的對象
    可以看到可以作為Roots的是程序員在方法調(diào)用的時候直接操縱的對象,而不是包含在對象的引用指向的對象。

  • 可以用弱引用和軟引用來實現(xiàn)內(nèi)存不足時對象回收問題。

可達性分析中的不可達對象也并不是馬上死亡,它需要經(jīng)歷至少兩次標記的過程。當對象沒有和GC Roots相連的時候,進行第一次標記,并且進行一次篩選,如果覆蓋了一個對象的finalize(),切沒被系統(tǒng)掉用過,方法會將改對象放入F-Queue中等待,然后調(diào)用finalize()方法,注意這個方法只被系統(tǒng)調(diào)用一次,如果這個時候?qū)ο筚x值給一個引用,那么這個對象將會被“救活”,反之,進行第二次標記然后被回收。

  • 方法區(qū)中的回收
    方法區(qū)也就是永久代,主要回收對象是廢棄常量和無用的類。廢棄常量以常量池中的字面量為列:常量池中有“abc”的String類型的字符串,如果沒有任何一個地方的字符引用為abc的話就被視為廢棄常量。而無用的類的判斷就復(fù)雜很多:
    1、該類所有的實例對象都已經(jīng)被回收,也就是內(nèi)存中不存在該類的實例對象
    2、該類的ClassLoader已經(jīng)被回收
    3、該類的Class對象沒有被引用,沒有在任何地方通過反射訪問。
垃圾回收算法
  • 標記-回收算法:效率低,容易產(chǎn)生大量的碎片
  • 復(fù)制算法:使用一半的內(nèi)存,當一塊內(nèi)存用完了,把這內(nèi)存存活的對象復(fù)制到另一塊上面,然后這塊內(nèi)存進行清除操作。
  • 標記-整理:將存活的對象移動到一遍,以此為界限,清除邊界以外的內(nèi)存
  • 分代收集算法:把堆內(nèi)存分為新生代、老年代。這樣就可以針對各個年代的特點采用適當?shù)幕厥账惴āP律诶厥彰看斡写罅康膶ο笏廊?,使用?fù)制算法;老年代對象存活比較久,用標記-整理算法或者標記-清除算法。

在發(fā)生GC時,所有的線程都是中斷的。所以在Android中發(fā)生內(nèi)存抖動,頻繁GC,會導(dǎo)致頁面卡頓等等需要性能優(yōu)化的地方。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容