關於Javascript記憶體洩露的那些小事兒

尛沫發表於2014-04-28

在曾經,即使Web頁面執行中真的出現了資源洩漏,那它的影響也是非常有限而且常常是不會被人在意的。而現如今,人們對Web應用有了高更的要求。一個頁面很可能數小時不會發生URL跳轉,並同時通過Web服務動態的更新頁面內容。複雜的事件關聯設計、基於物件的JScript和DHTML技術的廣泛採用,使得程式碼的能力達到了其承受的極限。還算好的是,當你明確了希望尋找什麼時,記憶體洩露方式是比較容易被確定的。大多數你能遇到的洩露問題我們都已經知道,你只需要少量額外的工作就會給你帶來好處。雖然在一些頁面中少量的小洩漏問題仍會發生,但是主要的問題還是很容易解決的。

1.什麼是記憶體洩露?

記憶體洩露是指分配給應用的記憶體不能被重新分配,即使在記憶體已經不被使用的時候。正常情況下,垃圾回收器在DOM元素和event處理器不被引用或訪問的時候回收它們。但是,IE的早些版本(IE7和之前)中記憶體洩露是很容易出現的,因為記憶體管理器不能正確理解Javascript生命週期而且在週期被打破(可以通過賦值為null實現)前不會回收記憶體。

2.為什麼你需要注意它?

在大型Web應用程式中記憶體洩露是一種常見的意外程式設計錯誤。記憶體洩露會降低Web應用程式的效能,直到浪費的記憶體超過了系統所能分配的,應用程式將不能使用。作為一Web開發者,開發一個滿足功能要求的應用程式只是第一步,效能要求和Web應用程式的成功是同樣重要的,更何況它可能會導致應用程式錯誤或瀏覽器崩潰。

3.Javascript中出現記憶體洩露的主要原因是什麼?

1)迴圈引用

一個很簡單的例子:一個DOM物件被一個Javascript物件引用,與此同時又引用同一個或其它的Javascript物件,這個DOM物件可能會引發記憶體洩露。這個DOM物件的引用將不會在指令碼停止的時候被垃圾回收器回收。要想破壞迴圈引用,引用DOM元素的物件或DOM物件的引用需要被賦值為null。

2)Javascript閉包

因為Javascript範圍的限制,許多實現依賴Javascript不包,請檢視我的前面的文章JavaScript Scope and Closure如果你想了解更多閉包方面的問題。

閉包可以導致記憶體洩露是因為內部方法保持一個對外部方法變數的引用,所以儘管方法返回了內部方法還可以繼續訪問在外部方法中定義的私有變數。對Javascript程式設計師來說最好的做法是在頁面過載前斷開所有的事件處理器。

3)DOM插入順序

當2個不同範圍的 DOM 物件連新增到一起的時候一個臨時的物件會被建立。這個DOM物件改變範圍到document時,那個臨時物件就沒用了。也就是說, DOM 物件應該按照從當前頁面存在的最上面的 DOM 元素開始往下直到剩下的 DOM 元素的順序新增,這樣它們就總是有同樣的範圍,不會產生臨時物件。

4)如何檢測?

記憶體洩露對開發者來說一般很難檢測因為它們是由一些大量程式碼中的意外的錯誤引起的,但它在系統記憶體不足前並不影響程式的功能。這就是為什麼會有人在很長時間的測試期中收集應用程式效能指標來測試效能。

最簡單的檢測記憶體洩露的方式是用工作管理員檢查記憶體使用情況。在Chrome瀏覽器的新選項卡中開啟應用並檢視記憶體使用量是不是越來越多。還有其他的除錯工具提供記憶體監視器,比如Chrome開發者工具。這是谷歌開者這網站中的堆分析的特性的教程。

本文為Anyforweb技術分享部落格,需要了解網站建設相關,請訪問anyforweb.com。

相關文章