前端的學(xué)習(xí)已經(jīng)進(jìn)入了一個(gè)艱難的上升期,越來越發(fā)現(xiàn)自己學(xué)習(xí)的東西還多得多,需要掌握的知識(shí)面寬廣了很多,知識(shí)點(diǎn)需要理解的深度也加深了很多。今天看到前端內(nèi)存泄漏相關(guān),自己總結(jié)總結(jié),也便于自己以后學(xué)習(xí)記憶。由于經(jīng)驗(yàn)所致,必然會(huì)有不足之處,歡迎指正!
什么是內(nèi)存
內(nèi)存是計(jì)算機(jī)中重要的部件之一,它是與CPU進(jìn)行溝通的橋梁。計(jì)算機(jī)中所有程序的運(yùn)行都是在內(nèi)存中進(jìn)行的,因此內(nèi)存的性能對(duì)計(jì)算機(jī)的影響非常大。
什么是內(nèi)存泄漏
內(nèi)存泄漏(Memory Leak)是指程序中己動(dòng)態(tài)分配的堆內(nèi)存由于某種原因程序未釋放或無法釋放,造成系統(tǒng)內(nèi)存的浪費(fèi),導(dǎo)致程序運(yùn)行速度減慢甚至系統(tǒng)崩潰等嚴(yán)重后果。 說白了就是 不再用到的內(nèi)存,沒有及時(shí)釋放,就叫做內(nèi)存泄漏(memory leak)。
看完上面的解釋,腦海中就會(huì)有一點(diǎn)概念,計(jì)算機(jī)正常運(yùn)轉(zhuǎn)會(huì)用到內(nèi)存,內(nèi)存像是一個(gè)中轉(zhuǎn)站,他把你暫存的數(shù)據(jù),馬上就會(huì)用到的數(shù)據(jù)存儲(chǔ)在這,以讓你更快捷方便的使用, 那你肯定會(huì)想到一個(gè)問題,暫存的數(shù)據(jù)到底哪些該存儲(chǔ)在這里,存儲(chǔ)的東西不會(huì)一直在這,又是怎么消失的呢?
在我的理解,前端開發(fā)中,全局的、被引用的對(duì)象就會(huì)被保存在內(nèi)存中。比如我們常見的閉包:
function leak(arg) {
this.arg = arg;
}
function test() {
var l1= new leak('It is a leak');
document.body.addEventListener('click', function() {
l1.arg = 'Here you are!'
})
}
test()
很明顯,l1被閉包環(huán)境引用,無法被回收
那么瀏覽器是怎么判斷一個(gè)對(duì)象是不是該被垃圾回收了呢
對(duì)前端開發(fā)來說只需要理解'引用計(jì)數(shù)法'就可以了 語(yǔ)言引擎有一張"引用表",保存了內(nèi)存里面所有的資源(通常是各種值)的引用次數(shù)。如果一個(gè)值的引用次數(shù)是0,就表示這個(gè)值不再用到了,因此可以將這塊內(nèi)存釋放。
代碼層面內(nèi)存泄露的原因
- 循環(huán)引用
- 閉包
- 全局變量
- 沒有清理的DOM元素引用
- 被遺忘的定時(shí)器以及其中的引用
可能造成了內(nèi)存泄漏要怎么排查
- 我們可以使用chrome瀏覽器調(diào)試工具中的內(nèi)存快照,點(diǎn)擊左上角灰色原點(diǎn)就可以保存一份快照,記錄此時(shí)內(nèi)存使用情況 可以看到代碼中明顯的l1對(duì)象被引用導(dǎo)致無法釋放,在快照中我們也看到了一個(gè)leak實(shí)例在內(nèi)存中。通過見=簡(jiǎn)單分析就可以知道是哪塊代碼出了問題


2. 如果是在Node環(huán)境下,可以用Node提供的process.memoryUsage()方法來檢查內(nèi)存泄露:具體方法可以參考阮一峰的例子:https://github.com/ruanyf/es6tutorial/issues/362#issuecomment-292451925
- rss (resident set size) : 所有內(nèi)存占用,包括指令區(qū)和堆棧。
- heapTotal : "堆"占用的內(nèi)存,包括用到的和未用到的。
- heapUsed : 用到的堆。
- external : V8引擎內(nèi)部C++對(duì)象占用的內(nèi)存。
判斷內(nèi)存泄露以heapUsed為準(zhǔn)。
如何處理
- 避免循環(huán)引用等發(fā)生源
- 變量導(dǎo)致的內(nèi)存泄露,將變量清除 a = null
- 事件監(jiān)聽導(dǎo)致的內(nèi)存泄露,監(jiān)聽后移除
作者:天微蔚藍(lán)
鏈接:https://juejin.im/post/5c6663a85188252a160efa3c
來源:掘金