魔鬼的夢魘 驗證IE中的JS記憶體洩露 二

2022-03-10 08:38:03 字數 1457 閱讀 4037

魔鬼的夢魘—驗證ie中的js記憶體洩露(二)

閉包往往是需要為記憶體洩露負責的,因為使用它會很容易產生不為程式設計師所發現的迴圈引用。父函式的引數和區域性變數將會一直被凍結、引用和持有,知道閉包本身被釋放,這並不是顯而易見的。事實上閉包已經變成如此普遍的變成策略,以至於開發人員經常的深陷問題之中,但是已存的我們可以依賴使用的資源卻很少。我們來看看這個使用了閉包的迴圈引用圖,它詳細的描述了閉包及其造成的沒存洩露的由來,並且指出了這些迴圈引用是如何形成的。

一般情況下的迴圈引用時由於兩個特定的物件彼此持有對方的引用造成的,但是閉包卻不一樣。它不是直接引用,而是其通過引入父函式的作用域資訊而產生的。正常情況下,乙個函式的區域性變數和引數僅僅在函式被呼叫的生命週期內才能被使用。但是只要閉包存在的話,這些變數和引數就一直被引用,並且由於閉包的生命週期可能會超過父函式,所以這些區域性變數和引數同樣也會。在這個原理圖(圖1)中,只要父函式一執行完,就會釋放對引數parameter1的引用。但是由於我們新增了乙個閉包,這個閉包又新增了自己對parameter1的引用,但是這個引用直到這個閉包被釋放的時候才會被釋放。如果以正好將這個閉包繫結到乙個事件,那麼最終你就需要解除對這個事件的繫結。如果你將這個閉包繫結到dom的屬性expando,那麼你最終頁需要將這個屬性重置為null。

圖 1. 閉包導致記憶體洩露原理圖

每呼叫一次函式就會產生乙個新的閉包物件,所以呼叫兩次父函式那麼就是產生兩個相互獨立的閉包物件,每乙個閉包都會引用產生自己的時候傳入的引數。這種顯而易見的特性是很容易導致記憶體洩露的。原理圖對應的物件引用關係圖如下(圖2)

圖 2. 閉包洩露原理圖物件引用關係圖

在這個模式中給出的例子也是使用的頁面中的dom元素,我們也是測試不到記憶體洩露的,因為本質上說這個也是由於迴圈引用導致。修改的可以導致洩露的**如下,具體的驗證就不貼出來了,有興趣的話可以自己測試一下

doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" ""

>

<

html 

xmlns

="">

<

head

>

<

script 

language

="jscript"

>

function attachevents(element) 

}function setupleak() 

function breakleak() 

script

>

head\

>

<

body 

onload

="setupleak()"

onunload

="breakleak()"

>

<

div 

id="leakeddiv"

>

div>

body

>

html

>

魔鬼的夢魘 驗證IE中的js記憶體洩露模式(三)

魔鬼的夢魘 驗證ie中的js記憶體洩露模式 三 按照justin rogers文章的順序,接下來的這個模式應該是跨頁記憶體洩露模式 cross page leak 但是由於這個模式產生的中間物件,我們並不能訪問到,所以我也想不到好的有可視效果的驗證方式,所以就不介紹了,有興趣的話大家可以看一下原文 ...

js在IE中的記憶體釋放問題

在ie下的js程式設計中,以下的程式設計方式都會造成即使關閉ie也無法釋放記憶體的問題,下面分類給出 1 給dom物件新增的屬性是乙個物件的引用。範例 var myobject document.getelementbyid mydiv myprop myobject 解決方法 在window.on...

程式中的魔鬼數字

在 中使用魔鬼數字 沒有具體含義的數字 字串等 將會導致 難以理解,應該將數字定義為名稱有意義的常量。將數字定義為常量的最終目的是為了使 更容易理解,所以並不是只要將數字定義為常量就不是魔鬼數字了。如果常量的名稱沒有意義,無法幫助理解 同樣是一種魔鬼數字。在個別情況下,將數字定義為常量反而會導致 更...