摘要:假如沒有此時會進行優(yōu)化把不會被任何閉包用到的變量從詞法環(huán)境中去掉從而消除內(nèi)存泄漏。良好的編碼方式了解一下常見現(xiàn)象可以減少內(nèi)存泄漏現(xiàn)象產(chǎn)生同時在由于失誤產(chǎn)生泄漏時保持清醒的思路借助進行分析定位。
引言
全局變量內(nèi)存泄漏一般是由于我們編碼缺陷導致的,首先明確一下內(nèi)存泄漏的定義,就是應用程序不需要,但是又不能返回給操作系統(tǒng)以供重新分配使用,導致可用內(nèi)存越來越少的現(xiàn)象。下面總結(jié)一下在browser端內(nèi)存泄漏幾種方式
function test () { age ="xxx" this.name = "ycg" } test()
說明
本來函數(shù)執(zhí)行完棧釋放,但是失誤行為,導致棧中本應該聲明為局部的變量變成了全局,導致變量所占用空間無法釋放,好的編碼習慣可以防止此類失誤,例如借助eslint等
var someResource = "jsdt".repeat(100000); setInterval(function() { var node = document.getElementById("node"); if(node) { // Do stuff with node and someResource. node.innerHTML = JSON.stringify(someResource); } }, 100);
說明 由于定時器中持有node節(jié)點引用,導致即使node節(jié)點被移除,所占據(jù)空間任然無法被釋放
閉包var theThing = null; var replaceThing = function () { var originalThing = theThing; // Define a closure that references originalThing but doesn"t ever // actually get called. But because this closure exists, // originalThing will be in the lexical environment for all // closures defined in replaceThing, instead of being optimized // out of it. If you remove this function, there is no leak. var unused = function () { if (originalThing) console.log("hi"); }; theThing = { longStr: new Date()+new Array(1000000).join("*"), // While originalThing is theoretically accessible by this // function, it obviously doesn"t use it. But because // originalThing is part of the lexical environment, someMethod // will hold a reference to originalThing, and so even though we // are replacing theThing with something that has no effective // way to reference the old value of theThing, the old value // will never get cleaned up! someMethod: function () {} }; // If you add `originalThing = null` here, there is no leak. }; setInterval(replaceThing, 1000);
說明 注釋中已經(jīng)很好的說明了產(chǎn)生現(xiàn)象的原因,就是說同一父級作用域創(chuàng)建的各種閉包作用域是共享的,unused引用originalThing,雖沒使用,但是詞法作用域環(huán)境已經(jīng)創(chuàng)建。假如沒有unused,此時v8會進行優(yōu)化,把不會被任何閉包用到的變量從詞法環(huán)境中去掉,從而消除內(nèi)存泄漏。下圖是我本地browser實驗現(xiàn)象截取,可以看到使用內(nèi)存一直在增加,并且從對比視圖中看到,一直有新的string被創(chuàng)建,只增不減。
圖示dom樹中,如果#tree變成游離態(tài),但是葉子節(jié)點leaf被js變量引用。除非消除引用,否則游離態(tài)的#tree無法被GC
總結(jié)首先必須明確的概念是瀏覽器不能幫助我們解決內(nèi)存泄漏,只是幫我們GC,免得人力手動GC。GC算法規(guī)則限制了只能清除符合特定條件的對象。良好的編碼方式,了解一下常見memory leak現(xiàn)象可以減少內(nèi)存泄漏現(xiàn)象產(chǎn)生,同時在由于失誤產(chǎn)生泄漏時,保持清醒的思路,借助devtool進行分析定位。
參考鏈接
https://blog.meteor.com/an-in...
https://blog.sessionstack.com...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/88992.html
摘要:積少成多,最后造成內(nèi)存泄漏。前端內(nèi)存泄漏的影響,都是發(fā)生在客戶機器上,而且基本上現(xiàn)代瀏覽器也會做好保護機制,一般自行刷新之后都會解決。但是,一旦后端繪制內(nèi)存泄漏造成宕機之后,整個服務(wù)器都會受影響,危險性更大,搞不好年終獎就沒了。 引言 Memory Leak 是最難排查調(diào)試的 Bug 種類之一,因為內(nèi)存泄漏是個 undecidable problem,只有開發(fā)者才能明確一塊內(nèi)存是不是需...
摘要:內(nèi)存泄漏會造成什么影響它是造成應用程序的主要原因之一。靜態(tài)變量引用不當會導致內(nèi)存泄漏靜態(tài)變量和會導致內(nèi)存泄漏,在下面這段代碼中對的和設(shè)置為靜態(tài)對象,從而產(chǎn)生內(nèi)存泄漏。 目錄介紹: 1.什么是內(nèi)存泄漏 2.內(nèi)存泄漏造成什么影響 3.內(nèi)存泄漏檢測的工具有哪些 4.關(guān)于Leakcanary使用介紹 5.Leakcanary捕捉常見的內(nèi)存泄漏及解決辦法 5.0.1 錯誤使用單例造成的內(nèi)存...
閱讀 1322·2023-04-26 03:05
閱讀 778·2021-10-19 11:43
閱讀 3228·2021-09-26 09:55
閱讀 835·2019-08-30 15:56
閱讀 991·2019-08-30 15:44
閱讀 1246·2019-08-30 15:44
閱讀 2726·2019-08-30 14:23
閱讀 3245·2019-08-30 13:13