1、什么是閉包、以及閉包所涉及的作用域鏈這里就不說了。
2、JavaScript垃圾回收機制
JavaScript不需要手動地釋放內存,它使用一種自動垃圾回收機制(garbage collection)。當一個對象無用的時候,即程序中無變量引用這個對象時,就會從內存中釋放掉這個變量。
3、循環引用
三個對象 A 、B 、C
AàBàC :A的某一屬性引用著B,同樣C也被B的屬性引用著。如果將A清除,那么B、C也被釋放。
AàBàCàB :這里增加了C的某一屬性引用B對象,如果這是清除A,那么B、C不會被釋放,因為B和C之間產生了循環引用。
4、循環引用和閉包
這是一種及其隱蔽的循環引用,。當調用一次outer時,就會在其內部創建obj和inner兩個對象,obj的inner屬性引用了inner;同樣inner也引用了obj,這是因為obj仍然在innerFun的封閉環境中,準確的講這是由于JavaScript特有的“作用域鏈”。
因此,閉包非常容易創建循環引用,幸運的是JavaScript能夠很好的處理這種循環引用。
5、IE中的內存泄漏
IE中的內存泄漏有好幾種,這里有詳細的解釋(http://msdn.microsoft.com/en-us/library/bb250448.aspx)。
這里只討論其中一種,即循環引用所造成的內存泄漏,因為,這是一種最普遍的情況。
當在DOM元素或一個ActiveX對象與普通JavaScript對象之間存在循環引用時,IE在釋放這類變量時存在特殊的困難,最好手動切斷循環引用,這個bug在IE 7中已經被修復了(http://www.quirksmode.org/blog/archives/2006/04/ie_7_and_javasc.html)。
“IE 6 suffered from memory leaks when a circular reference between several objects, among which at least one DOM node, was created. This problem has been solved in IE 7. ”
如果上面的例子(第4點)中obj引用的不是一個JavaScript Function對象(inner),而是一個ActiveX對象或Dom元素,這樣在IE中所形成的循環引用無法得到釋放。
Elem引用了它的click事件的監聽函數,同樣該函數通過其作用域鏈也引用回了elem元素。這樣在IE中即使離開當前頁面也不會釋放這些循環引用。
6、解決方法
基本的方法就是手動清除這種循環引用,下面一個十分簡單的例子,實際應用時可以自己構建一個addEvent()函數,并且在window的unload事件上對所有事件綁定進行清除。
其它方法(by:Douglas Crockford)
以上就是JavaScript內存泄漏的相關內容以及解決方案了,有需要的小伙伴可以參考下
新聞熱點
疑難解答