JS常見內(nèi)存泄漏及解決方案解析
內(nèi)存泄漏?
官方解釋:內(nèi)存泄漏(Memory Leak)是指程序中己動態(tài)分配的堆內(nèi)存由于某種原因程序未釋放或無法釋放,造成系統(tǒng)內(nèi)存的浪費,導(dǎo)致程序運行速度減慢甚至系統(tǒng)崩潰等嚴重后果。
通俗點就是指由于疏忽或者錯誤造成程序未能釋放已經(jīng)不再使用的內(nèi)存,不再用到的內(nèi)存卻沒有及時釋放,從而造成內(nèi)存上的浪費。
避免內(nèi)存泄漏?
在局部作用域中,等函數(shù)執(zhí)行完畢,變量就沒有存在的必要了,垃圾回收機制很虧地做出判斷并且回收,但是對于全局變量,很難判斷什么時候不用這些變量,無法正常回收;所以,盡量少使用全局變量。在使用閉包的時候,就會造成嚴重的內(nèi)存泄漏,因為閉包中的局部變量,會一直保存在內(nèi)存中。
內(nèi)存溢出?
當程序運行需要的內(nèi)存超過了剩余的內(nèi)存時, 就出拋出內(nèi)存溢出的錯誤。
例如下面的代碼,謹慎試用,可能會卡窗口。。。。
var obj = {}
for (var i = 0; i < 100000; i++) {
obj[i] = new Array(10000000)
}
console.log('------')
常見的js內(nèi)存泄漏
1. 意外的全局變量
在js中,一個未聲明變量的使用,會在全局對象中創(chuàng)建一個新的變量;在瀏覽器環(huán)境下,全局對象就是window:
function foo() {
a = 'test'
}
// 上面的寫法等價于
function foo() {
window.a = 'test'
}
function foo() {
this.a = 'test'
// 函數(shù)自身發(fā)生調(diào)用,this指向全局對象window
}
foo();
上面的a變量應(yīng)該是foo()內(nèi)部作用域變量的引用,由于沒有使用var來聲明這個變量,這時變量a就被創(chuàng)建成了全局變量,這個就是錯誤的,會導(dǎo)致內(nèi)存泄漏。
解決方式: 在js文件開頭添加 ‘use strict',開啟嚴格模式。(或者一般將使用過后的全局變量設(shè)置為 null 或者將它重新賦值,這個會涉及的緩存的問題,需要注意)
<script>
"use strict";
console.log("這是嚴格模式。");
</script>
<script>
console.log("這是正常模式。");
</script>
2. 計時器和回調(diào)函數(shù)timers
定時器setInterval或者setTimeout在不需要使用的時候,沒有被clear,導(dǎo)致定時器的回調(diào)函數(shù)及其內(nèi)部依賴的變量都不能被回收,這就會造成內(nèi)存泄漏。
解決方式:當不需要interval或者timeout的時候,調(diào)用clearInterval或者clearTimeout
3. DOM泄漏
1)給DOM對象添加的屬性是一個對象的引用
var a = {};
document.getElementById('id').diyProp = a;
解決方法:在window.onload時間中加上 document.getElementById('id').diyProp = null;
2)元素引用沒有清理
var a = document.getElementById('id');
document.body.removeChild(a);
// 不能回收,因為存在變量a對它的引用。雖然我們用removeChild移除了,但是還在對象里保存著#的引用,即DOM元素還在內(nèi)存里面。
解決方法: a = null;
3)事件的綁定沒有移除
解決方法: 移除時間的監(jiān)聽
4. js閉包
閉包在IE6下會造成內(nèi)存泄漏,但是現(xiàn)在已經(jīng)無須考慮了。值得注意的是閉包本身不會造成內(nèi)存泄漏,但閉包過多很容易導(dǎo)致內(nèi)存泄漏。閉包會造成對象引用的生命周期脫離當前函數(shù)的上下文,如果閉包如果使用不當,可以導(dǎo)致環(huán)形引用(circular reference),類似于死鎖,只能避免,無法發(fā)生之后解決,即使有垃圾回收也還是會內(nèi)存泄露。
這個,另外找個時間詳細說明一下,這里就不贅述了
5. console
控制臺日志記錄對總體內(nèi)存內(nèi)置文件的影響,也是個重大的問題,同時也是容易被忽略的。記錄錯誤的對象,可以將大量的數(shù)據(jù)保留在內(nèi)存中。傳遞給console.log的對象是不能被垃圾回收,所以沒有去掉console.log可能會存在內(nèi)存泄漏
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JS實現(xiàn)CheckBox復(fù)選框全選全不選功能
在網(wǎng)站的管理后臺應(yīng)用此功能居多,如一次性處理多個產(chǎn)品,或?qū)ξ恼碌膭h除對產(chǎn)品的下架等處理,一條一條的點顯然有一些麻煩,如果能每一行放一個checkbox,然后統(tǒng)一處理就好辦的多了,今天我就用簡單的篇幅來講解一下這個功能的實現(xiàn)原理和實現(xiàn)過程。2015-05-05
Javacript實現(xiàn)顏色梯度變化和漸變的效果代碼
用js對導(dǎo)航欄的顏色做了梯度的變化處理,通過處理..獲取兩種顏色在變化時的各種顏色字符串,并且字符串的個數(shù),即獲取的頻率可以調(diào)節(jié)2013-05-05
原生js實現(xiàn)的貪吃蛇網(wǎng)頁版游戲完整實例
這篇文章主要介紹了原生js實現(xiàn)的貪吃蛇網(wǎng)頁版游戲完整實例,可實現(xiàn)自主選擇游戲難度進行貪吃蛇游戲的功能,涉及javascript鍵盤事件及頁面元素的操作技巧,需要的朋友可以參考下2015-05-05
bootstrapfileinput實現(xiàn)文件自動上傳
這篇文章主要介紹了bootstrapfileinput實現(xiàn)文件自動上傳,bootstrap fileinput插件對多種類型的文件提供文件預(yù)覽,并且提供了多選等功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-11-11

