JavaScript記憶體回收機制深入解讀

來源:互聯網
上載者:User

JavaScript語言是一門優秀的指令碼語言.其中包含指令碼語言的靈活性外還擁有許多進階語言的特性.例如充許構建和執行個體化一個對象,垃圾回

收機制(GC:Garbage
Collecation).通常我們使用new建立對象,GC負責回收對象佔用記憶體地區.因此瞭解GC,可以加深對JavaScript記憶體回收

機制的理解。

1.用局部變數和全域變數解釋GC

GC在回收記憶體時,首先會判斷該對象是否被其它對象引用.在確定沒有其它對象引用便釋放該對象記憶體地區.因此如何確定對象不再被引用是

GC的關鍵所在.

 
  1. <script>
  2. function aa(){
  3. this.rr = "彈窗";
  4. }
  5. function bb(){
  6. this.rr = "彈窗";
  7. }
  8. var b1;
  9. function cc(){
  10. var a1 = new aa();
  11. b1 = new bb();
  12. return b1;
  13. }
  14. cc();
  15. alert(b1.rr)
  16. </script>

如上代碼中,執行完cc()後a1被回收了,此後我們可以通過b1.rr彈出文字視窗.在一些基礎書籍中解釋為:a1為局部變數,b1是全域變數.局部

變數執行完後會被GC回收.但不全是這樣,如下代碼:

 
  1. <script>
  2. function aa(){
  3. this.rr = "彈窗";
  4. }
  5. function bb(){
  6. this.rr = "彈窗";
  7. }
  8. function cc(){
  9. var a1 = new aa();
  10. var b1 = new bb();
  11. return b1;
  12. }
  13. var b1 = cc();
  14. alert(b1.rr);
  15. </script>

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

2.抽象理解GC

GC回收機制還需要近一步瞭解。在此時引入幾個概念:雙向鏈表,範圍鏈,使用中的物件(為了方便理解,簡化了原文的概念

[http://softbbs.pconline.com.cn/9497825.html]) , 其中雙向鏈表描述複雜物件的上下層級關係.
範圍鏈與使用中的物件分別是雙向鏈表

中的某個節點.以函數cc為例變數層級關係為:

 
  1. window<=>cc<=>a1<=>rr
  2. <=>b1<=>rr

(原文有詳細解釋)在執行cc()方法時,記憶體中變數的參考關聯性如,文字解釋如下:

window的使用中的物件包括cc,假設window是頂級對象(因為運行中不會被回收)

cc的使用中的物件包括a1和b1,其範圍鏈是window

a1的使用中的物件包括rr,其範圍鏈是cc

b1的使用中的物件包括rr,其範圍鏈是cc

執行cc()時,cc的執行環境會建立一個使用中的物件和一個範圍鏈.其局部變數a1,b1都會掛在cc的使用中的物件中.當cc()執行完畢後,執行環境

會嘗試回收使用中的物件佔用的記憶體.但因局部變數b1 通過return
b1,為其增加了一條範圍鏈:window<=>b1<=>rr,所以GC停止對b1回收.

因此如果想將一個局部變數/函數提升為全域的,為其增加一條範圍鏈就OK了。

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

 
  1. <SCRIPT LANGUAGE="JavaScript">
  2. <!--
  3. //貓
  4. function cat(name){
  5. var zhuren ;
  6. this.name = name;
  7. //設定主人
  8. this.addZhuRen = function(zr){
  9. zhuren = zr;
  10. }
  11. this.getZhuRen = function(){
  12. return zhuren;
  13. }
  14. }
  15. //主人
  16. function zhuren(name){
  17. this.name = name;
  18. }
  19. //建立主人:
  20. var zr = new zhuren("zhangsan");
  21. //建立貓
  22. var cat1 = new cat("asan");
  23. //設定該貓的主人
  24. cat1.addZhuRen(zr);
  25. //釋放主人
  26. zr = null ;
  27. //此處還存在對主人對象的引用
  28. alert(cat1.getZhuRen().name)
  29. //-->
  30. </SCRIPT>
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.