2011-12-06 19 views
3

我是新來的JavaScript,似乎有點問題追蹤內存泄漏。由於代碼相當複雜,我將它縮小到似乎導致內存泄漏的部分。我會發佈一個不重要的例子,但它會導致同樣的問題(只是小得多)。當前瀏覽器中的閉包和(jQuery)DOM事件發生內存泄漏?

Code Example

基本上,我有一些代碼,動態創建HTML和將事件附加到HTML。 HTML會在每次AJAX請求時重建。這一切都工作正常,第一次,但每個AJAX請求後,瀏覽器內存上升(不總是相等)!通過點擊jsfiddle上的多次運行並觀看瀏覽器內存,可以重現此問題。我的假設是,創建的閉包不會被垃圾收集,但我不確定?如果是這樣的話,是否有更好的方法來做到這一點,沒有關閉不會導致任何問題?

這發生在FF8,Chrome的最新版本和IE 8中。最有可能的是所有其他 - 正是我測試過的。

我已經在應該幫助的代碼中加入了一些註釋。

謝謝!好吧,在使用sIEve做了一些更多的研究之後,我可以看到DOM節點的數量在每個AJAX調用中翻倍。我已經更新了這個例子來模擬這個。所以我的問題是,爲什麼調用jQuery的空元素或刪除函數後不收集DOM元素?我也通過解除綁定的事件處理程序,並設置每個DOM元素JS參考,而不會影響到空的東西的元素環......

Code Example

+0

有IE6和一些HTML/DOM-JS內存問題(問題是DOM有一個內存模型和JS引擎有另一個,試圖解決這兩個問題),雖然我認爲這已經基本解決了......不知道現代瀏覽器中是否有任何當前的「陷阱」。 – 2011-12-06 22:53:15

+0

我無法在最新的Chrome上重現此操作:/ –

+0

可能想說出Chrome的「最新版本」,因爲它不總是相同的。另外,指定使用的jQuery版本。 :) [舊版本的jQuery有事件發生內存泄漏。](http://bugs.jquery.com/ticket/5285) – 2011-12-06 22:57:45

回答

1

這是很平常的程序分配內存,看到它的內存使用量增加,然後在釋放內存時不會改變。這是底層操作系統如何管理內存的結果,不一定引起關注,也不一定是「問題」。通常,您應該使用其他工具來定位程序中的內存泄漏(無論它們是本機代碼還是居於瀏覽器中),而不是依賴跟蹤整體流程統計信息的系統工具。

0

你只需要注意瀏覽器的內存使用情況。作爲測量的更準確的測試是多次運行代碼,然後查看瀏覽器的內存使用情況,然後運行更多次並比較新的數字。

通常情況下,瀏覽器不會反映只是使用javascript。所以,它的內存使用量可能會波動,而您的代碼無法泄露。

0

有一個技巧可以減少/避免內存泄漏,至少在IE中。

你可以嘗試一下,看看內存是否比你現在的方法更快。
它首先在DOM中插入HTML,然後附加事件。

0

我與ShaggyFrog在這一個。您可以通過刪除本地變量來減少內存分配,並在完成後手動清空appendUs陣列。在Chrome中,每次運行腳本時,我都看到內存分配跳躍了800KB - 1MB。如上所述製作small changes to your code將每次運行的附加內存分配減少到400-500KB(平均來說,通過手動觀察任務管理器)。

這樣說,行爲可能只是Windows和/或Chrome及其內存管理。將JSFiddle頁面閒置一段時間後,Chrome的內存使用率回落到開始運行示例之前的位置。最終發生了某種垃圾收集,只是可能沒有你期望的那樣快。

3

這與DOM的GC和JavaScript GC不是朋友有關。基本的要點是,如果某個東西被DOM引用,JS GC可能不會銷燬它,反之亦然。這個想法可能過時了,因爲它出現在Crockford的幾本瀏覽器老版本的書中。

我在這裏看到一些潛在的問題,這可能是特定的JS小提琴,但可能不是:

  • 是否有必要指定F·在每次運行
  • 你正在創建DOM元素很多在這裏一次一個,
  • 你重新創建女,所以這個問題更可能在DOM的GC不是JavaScript的GC
  • JavaScript的GC是一個標記掃描掃描器,這意味着它是「懶惰」。你可以在你的腳本中看到這個 - 如果你運行它十次,內存使用量會非常高,但最終被遺棄的對象會被垃圾收集,並且內存使用量會下降。
  • 您必須擔心的關閉是分配給click元素的閉包,但您在此處未使用閉包。

但是我沒有看到任何真正的問題,幾分鐘後我的內存使用率回落到正常水平。

總之,你沒有內存泄漏(至少按下一個),你的JS解釋器的GC只是懶惰。你放棄了很多DOM元素,這並不好,這也是你的記憶力強勁的原因,但這是一個短期的性能問題,而不是長期的頁面加載問題。