歡迎光臨
每天分享高質量文章

JavaScript中的內存泄露模式

JavaScript 是用來向 Web 頁面添加動態內容的一種功能強大的腳本語言。它尤其特別有助於一些日常任務,比如驗證密碼和創建動態選單組件。JavaScript 易學易用,但卻很容易在某些瀏覽器中引起記憶體的泄漏。在這個介紹性的文章中,我們解釋了 JavaScript 中的泄漏由何引起,展示了常見的記憶體泄漏樣式,並介紹瞭如何應對它們。

註意本文假設您已經非常熟悉使用 JavaScript 和 DOM 元素來開發 Web 應用程式。本文尤其適合使用 JavaScript 進行 Web 應用程式開發的開發人員,也可供有興趣創建 Web 應用程式的客戶提供瀏覽器支持以及負責瀏覽器故障排除的人員參考。

我的瀏覽器存在泄漏麽?

Internet Explorer 和 Mozilla Firefox 是兩個與 JavaScript 中的記憶體泄漏聯繫最為緊密的瀏覽器。兩個瀏覽器中造成這種問題的“罪魁禍首”是用來管理 DOM 物件的組件物件模型。本機 Windows COM 和 Mozilla’s XPCOM 都使用取用計數的垃圾收集來進行記憶體分配和檢索。取用計數與用於 JavaScript 的標記-清除式的垃圾收集並不總是能相互兼容。本文側重介紹的是如何應對 JavaScript 代碼中的記憶體泄漏。有關如何處理 Firefox 和 IE 中 COM 層記憶體泄漏的更多信息,請參看 參考資料。

JavaScript 中的記憶體泄漏

JavaScript 是一種垃圾收集式語言,這就是說,記憶體是根據物件的創建分配給該物件的,並會在沒有對該物件的取用時由瀏覽器收回。JavaScript 的垃圾收集機制本身並沒有問題,但瀏覽器在為 DOM 物件分配和恢復記憶體的方式上卻有些出入。

Internet Explorer 和 Mozilla Firefox 均使用取用計數來為 DOM 物件處理記憶體。在取用計數系統,每個所取用的物件都會保留一個計數,以獲悉有多少物件正在取用它。如果計數為零,該物件就會被銷毀,其占用的記憶體也會傳回給堆。雖然這種解決方案總的來說還算有效,但在迴圈取用方面卻存在一些盲點。

迴圈取用的問題何在?

當兩個物件互相取用時,就構成了迴圈取用,其中每個物件的取用計數值都被賦 1。在純垃圾收集系統中,迴圈取用問題不大:若涉及到的兩個物件中的一個物件被任何其他物件取用,那麼這兩個物件都將被垃圾收集。而在取用計數系統,這兩個物件都不能被銷毀,原因是取用計數永遠不能為零。在同時使用了垃圾收集和取用計數的混合系統中,將會發生泄漏,因為系統不能正確識別迴圈取用。在這種情況下,DOM 物件和 JavaScript 物件均不能被銷毀。清單 1 顯示了在 JavaScript 物件和 DOM 物件間存在的一個迴圈取用。

清單 1. 迴圈取用導致了記憶體泄漏

分享創造快樂