垃圾收集器

垃圾收集器如何判斷內(nèi)存是否需要回收

java的內(nèi)存分配有:程序計數(shù)器、虛擬機棧、本地方法棧、java堆、方法區(qū)
其中程序計數(shù)器、虛擬機棧、本地方法棧隨著線程而生、線程而死,而內(nèi)存的分配在類結構確定下來就已經(jīng)確定了,在內(nèi)存大小和回收時機上是確定的。而java堆和方法區(qū)就比較麻煩,我們只有在程序運行時,才知道要分配多大的空間,而什么時候創(chuàng)建和回收也是不確定的。

回收策略

引用計數(shù)法

給對象添加一個引用計數(shù)器,每當有一個地方引用它,就給計數(shù)器+1;引用失效,計數(shù)器-1,當引用技術器為0時就判定對象可以回收。

可達性分析

引用計數(shù)法是不靠譜的,如果兩個對象中各有一個字段引用對方對象,而對象本身卻已經(jīng)不可能再被訪問了,可是引用計數(shù)法都不為0,在這種情況下GC回收器還是會回收內(nèi)存的。代碼如下:

public class ReferenceCountingGC {
    public Object instance = null;

    public static void main(String[] args) throws Exception {
        ReferenceCountingGC objA = new ReferenceCountingGC();
        ReferenceCountingGC objB = new ReferenceCountingGC();
        objA.instance = objB;
        objB.instance = objA;

        objA = null;
        objB = null;

        System.gc();
    }
}

所以在java語言中并沒有采用引用技術法作為回收策略,使用了可達性分析算法
可達性分析算法中,定義了一種名為“GC Root”的對象,對象之間的引用構成圖,凡是被“GC Root”為起點,走過的路徑稱為引用鏈,引用鏈上的對象不會被回收。
哪些是“GC Root”對象呢?

  • 虛擬機棧(本地變量表)中引用的對象。
  • 方法區(qū)中類的靜態(tài)變量引用的對象。
  • 方法區(qū)中常量引用的對象。
  • 本地方法棧中引用的對象。

回收方法區(qū)

上面說到的對象回收是發(fā)生在java堆中,而方法區(qū)也是有回收垃圾的,主要回收廢棄常量和無用的類

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容