遺漏的計時器或回撥函式如何在 JavaScript 中導致記憶體洩漏?
遺漏的計時器/回撥函式
JavaScript 中有兩個計時事件,分別是 `setTimeout()` 和 `setInterval()`。前者在等待指定毫秒數後執行函式,而後者則定期執行函式(每隔一定時間間隔重複執行)。
當任何物件繫結到計時器回撥函式時,它將不會被釋放,直到超時發生。在這種情況下,計時器會重置自身並永遠執行,直到超時完成,從而阻止垃圾收集器回收記憶體。這些計時器是 JavaScript 中記憶體洩漏最常見的原因。
示例
在下面的示例中,計時器回撥函式及其繫結的物件 (tiedObject) 將不會被釋放,直到超時完成。同時,計時器會重置自身並永遠執行,因此即使沒有對原始物件的引用,其記憶體空間也永遠不會被回收。
<html> <body> <script> for (var i = 0; i < 100000; i++) { var tiedObject = { callAgain: function() { var text = this; var value = setTimeout(function() { text.callAgain(); }, 100000); } } tiedObject.callAgain(); tiedObject = null; } </script> </body>> </html>
避免記憶體洩漏
1. 為避免洩漏,在 `setInterval()`/`setTimeout()` 內提供引用,以便在垃圾收集之前需要執行函式。
2. 直接呼叫移除不再需要的函式。
除了 IE 等舊瀏覽器外,大多數現代瀏覽器(如 Chrome 等)都不會遇到此類問題。更重要的是,像 jQuery 這樣的庫會在內部進行處理,以確保不會產生洩漏問題。
廣告