JavaScript的垃圾回收機制

JavaScript語言是一門優秀的腳本語言。其中包含腳本語言的靈活性外還擁有許多高級語言的特性。例如充許構建和實例化一個對象,垃圾回收機制(GC:Garbage Collecation)。通常我們使用new創建對象,GC負責回收對象佔用內存區域。因此瞭解GC,可以加深對javascript垃圾回收機制的理解。

GC在回收內存時,首先會判斷該對象是否被其它對象引用。在確定沒有其它對象引用便釋放該對象內存區域。因此如何確定對象不再被引用是GC的關鍵所在。

<script type="text/javascript">
function aa()
{
    this.rr = "彈窗";    
}

function bb()
{
    this.rr = "彈窗";
}

var b1;

function cc()
{
    var a1 = new aa();
    b1 = new bb();
    return b1;
}

cc();
alert(b1.rr)
</script>

如上代碼中,執行完cc()後a1被回收了,此後我們可以通過b1.rr彈出文字窗口。在一些基礎書籍中解釋爲:a1爲局部變量,b1是全局變量。局部變量執行完後會被GC回收.但不全是這樣,如下代碼:

<script type="text/javascript">
function aa()
{
    this.rr = "彈窗";    
}

function bb()
{
    this.rr = "彈窗";
}

function cc()
{
    var a1 = new aa();
    var b1 = new bb();
    return b1;
}

var b1 = cc();
alert(b1.rr);
</script>

此時cc函數中的 a1,b1都是局部變量,但仍然會彈出文字窗口。說明b1並沒有被GC回收。因此javascript中局部變量不是所有時候都被GC回收的。

GC回收機制還需要近一步瞭解。在此時引入幾個概念:雙向鏈表,作用域鏈,活動對象(爲了方便理解,簡化了原文的概念[http://softbbs。pconline。com。cn/9497825。html]) , 其中雙向鏈表描述複雜對象的上下層級關係。 作用域鏈與活動對象分別是雙向鏈表中的某個節點。以函數cc爲例變量層級關係爲:

window<=>cc<=>a1<=>rr
<=>b1<=>rr

在執行cc()方法時,內存中變量的引用關係如上圖,文字解釋如下:

  1. cc的活動對象包括a1和b1,其作用域鏈是window
  2. cc的活動對象包括a1和b1,其作用域鏈是window
  3. a1的活動對象包括rr,其作用域鏈是cc
  4. b1的活動對象包括rr,其作用域鏈是cc

執行cc()時,cc的執行環境會創建一個活動對象和一個作用域鏈。其局部變量a1,b1都會掛在cc的活動對象中。當cc()執行完畢後,執行環境會嘗試回收活動對象佔用的內存。但因局部變量b1 通過return b1,爲其增加了一條作用域鏈:window<=>b1<=>rr,所以GC停止對b1回收。因此如果想將一個局部變量/函數提升爲全局的,爲其增加一條作用域鏈就OK了。

同時控制好對象的作用域鏈也變得重要了。因作用域鏈會意外導致GC無法回收目標對象。例如:

<SCRIPT LANGUAGE="JavaScript">
<!--
//
function cat(name)
{
    var zhuren ;
    this.name = name;
        
    //設置主人
    this.addZhuRen = function(zr){
        zhuren = zr;
    }

    this.getZhuRen = function(){
        return zhuren;
    }
}
    
//主人
function zhuren(name){
    this.name = name;
}

//創建主人:
var zr = new zhuren("zhangsan");
//創建貓
var cat1 = new cat("asan");
//設置該貓的主人
cat1.addZhuRen(zr);
//釋放主人
zr = null ;
//此處還存在對主人對象的引用
alert(cat1.getZhuRen().name)
//-->
</SCRIPT>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章