簡體   English   中英

這是垃圾收集?

[英]Is this garbage collected?

我確信以前曾經問過類似的問題,但是沒有回答我問題的大量類似問題迫使我要求自己。

假設您有以下代碼:

(function() {
    "use strict";
    var somearray=[1, 2, 3];
    for(var i=0; i<somearray.length; i++) {
        //do something
        }
    function loop() {
        //do something repeatedly
        requestAnimationFrame(loop);
        }
    loop();
    })();

由於變量i在與永久循環相同的范圍內定義,即使未使用它也會繼續存在,等待它最終可能被使用的可能性? 或者JavaScript(特別是Chrome的V8)垃圾收集器是否足夠聰明,以確定它是否會被使用?

我知道我可以將console.log(i)添加到某個地方的循環中,然后只要它被引用, i將繼續存在,但是它會繼續存在在一個繼續存在的范圍內未引用嗎?

這不是關於垃圾收集器的問題,而是關於閉包是否被優化的問題。 執行環境的閉包優化器可能確定嵌套函數不引用(關閉)變量,然后從閉包環境中忽略它們。 如果是這樣的話,那么他們就是收集的候選人。 如果未運行閉包優化器,或者它確定isomearray被引用,或者它無法確定isomearray的生命周期,那么它們將不會被收集,因為閉包環境需要它們。

函數有一個隱式環境,它包含封閉函數中的所有局部變量(以及包含它的所有函數)。 此環境將捕獲這些變量引用的任何對象。 閉包優化器靜態分析函數以確定是否可以修剪環境以忽略未引用的變量。 如果變量從環境中刪除,則一旦函數調用結束,它們就是候選者。

所有現代JavaScript引擎都有一個閉包優化器。

可能禁用或限制閉包優化器的一些常見事情包括處於調試模式,使用直接eval() ,使用arguments數組,使用不推薦使用的eval()caller

正如您所看到的,它顯然取決於\\\\do something repeatedly執行的操作以及代碼執行的上下文。

確保不會捕獲它們而不管\\\\do something repeatedly是確保它們不再在范圍內。 一個立即執行的函數將執行此操作,以便將代碼更改為,

(function() {
  "use strict";
  (function() {
    var somearray=[1, 2, 3];
    for(var i=0; i<somearray.length; i++) {
      //do something
    }
   })();
  function loop() {
    //do something repeatedly
    requestAnimationFrame(loop);
  }
  loop();
})();

將確保陣列不會留在內存中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM