摘要:前言內(nèi)存泄漏指由于疏忽或錯(cuò)誤造成程序未能釋放已經(jīng)不再使用的內(nèi)存。這里就講一些常見會(huì)帶來內(nèi)存泄露的原因。解決方案和都設(shè)為。
前言
內(nèi)存泄漏指由于疏忽或錯(cuò)誤造成程序未能釋放已經(jīng)不再使用的內(nèi)存。內(nèi)存泄漏并非指內(nèi)存在物理上的消失,而是應(yīng)用程序分配某段內(nèi)存后,由于設(shè)計(jì)錯(cuò)誤,導(dǎo)致在釋放該段內(nèi)存之前就失去了對(duì)該段內(nèi)存的控制,從而造成了內(nèi)存的浪費(fèi)。這里就講一些常見會(huì)帶來內(nèi)存泄露的原因。
0. 全局變量JavaScript自由的其中一種方式是它可以處理沒有聲明的變量:一個(gè)未聲明的變量的引用在全局對(duì)象中創(chuàng)建了一個(gè)新變量。在瀏覽器的環(huán)境中,全局對(duì)象是window。
function foo(){ name = "前端曰"; } // 其實(shí)是把name變量掛載在window對(duì)象上 function foo(){ window.name = "前端曰"; } // 又或者 function foo(){ this.name = "前端曰"; } foo() // 其實(shí)這里的this就是指向的window對(duì)象
這樣無意中一個(gè)意外的全局變量就被創(chuàng)建了,為了阻止這種錯(cuò)誤發(fā)生,在你的Javascript文件最前面添加 "use strict;" 。這開啟了解析JavaScript的阻止意外全局的更嚴(yán)格的模式。或者自己注意好變量的定義!
1. 循環(huán)引用在js的內(nèi)存管理環(huán)境中,對(duì)象 A 如果有訪問對(duì)象 B 的權(quán)限,叫做對(duì)象 A 引用對(duì)象 B。引用計(jì)數(shù)的策略是將“對(duì)象是否不再需要”簡化成“對(duì)象有沒有其他對(duì)象引用到它”,如果沒有對(duì)象引用這個(gè)對(duì)象,那么這個(gè)對(duì)象將會(huì)被回收 。
function func() { let obj1 = {}; let obj2 = {}; obj1.a = obj2; // obj1 引用 obj2 obj2.a = obj1; // obj2 引用 obj1 }
當(dāng)函數(shù) func 執(zhí)行結(jié)束后,返回值為 undefined,所以整個(gè)函數(shù)以及內(nèi)部的變量都應(yīng)該被回收,但根據(jù)引用計(jì)數(shù)方法,obj1 和 obj2 的引用次數(shù)都不為 0,所以他們不會(huì)被回收。要解決循環(huán)引用的問題,最好是在不使用它們的時(shí)候手工將它們?cè)O(shè)為空。
解決方案:obj1 和 obj2 都設(shè)為 null 。
2. 老生常談的閉包閉包:匿名函數(shù)可以訪問父級(jí)作用域的變量。
var names = (function(){ var name = "js-say"; return function(){ console.log(name); } })()
閉包會(huì)造成對(duì)象引用的生命周期脫離當(dāng)前函數(shù)的上下文,如果閉包如果使用不當(dāng),可以導(dǎo)致環(huán)形引用(circular reference),類似于死鎖,只能避免,無法發(fā)生之后解決,即使有垃圾回收也還是會(huì)內(nèi)存泄露。
3. 被遺忘的延時(shí)器/定時(shí)器在我們的日常需求中,可能會(huì)經(jīng)常試用到 setInterval/setTimeout ,但是使用完之后通常忘記清理。
var someResource = getData(); setInterval(function() { var node = document.getElementById("Node"); if(node) { // 處理 node 和 someResource node.innerHTML = JSON.stringify(someResource)); } }, 1000);
setInterval/setTimeout 中的 this 指向的是window對(duì)象,所以內(nèi)部定義的變量也掛載到了全局;if 內(nèi)引用了 someResource 變量,如果沒有清除 setInterval/setTimeout 的話someResource 也得不到釋放;同理其實(shí) setTimeout 也一樣。所以我們用完需要記得去 clearInterval/clearTimeout。
4. DOM引起的內(nèi)存泄露未清除DOM引用
var refA = document.getElementById("refA"); document.body.removeChild(refA); // #refA不能回收,因?yàn)榇嬖谧兞縭efA對(duì)它的引用。將其對(duì)#refA引用釋放,但還是無法回收#refA。
解決方案:refA = null 。
DOM對(duì)象添加的屬性是一個(gè)對(duì)象的引用
var MyObject = {}; document.getElementById("myDiv").myProp = MyObject;
解決方案:在頁面 onunload 事件中釋放 document.getElementById("myDiv").myProp = null; 。
DOM被刪除或清空沒有清楚綁定事件這種情況應(yīng)該是比較常見的,同時(shí)也應(yīng)該是比較容易被忽略的。
給DOM對(duì)象綁定事件
var btn = document.getElementById("myBtn"); btn.onclick = function(){ document.getElementById("myDiv").innerHTML = "wechat: js-say"; } document.body.removeChild(btn); btn = null;
這里把DOM移除了,但是綁定的事件仍沒被移除,會(huì)引起內(nèi)存泄露所以需要清除事件。
var btn = document.getElementById("myBtn"); btn.onclick = function(){ btn.onclick = null; document.getElementById("myDiv").innerHTML = "wechat: js-say"; } document.body.removeChild(btn); btn = null;小廣告
我自己運(yùn)營的公眾號(hào),記錄我自己的成長!
每周至少一篇博客,拒絕拖延從我做起!
公眾號(hào):前端曰
公眾號(hào)ID:js-say
ps:是(yue)不是(ri)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/104352.html
摘要:解決方式是,當(dāng)我們不使用它們的時(shí)候,手動(dòng)切斷鏈接淘汰把和對(duì)象轉(zhuǎn)為了真正的對(duì)象,避免了使用這種垃圾收集策略,消除了以下常見的內(nèi)存泄漏的主要原因。以上參考資料高程垃圾收集類內(nèi)存泄漏及如何避免內(nèi)存泄露及解決方案詳解類內(nèi)存泄漏及如何避免 showImg(http://ww1.sinaimg.cn/large/005Y4rCogy1ft1ikzcqzqj30ka0et77a.jpg); 前言 起...
摘要:應(yīng)用常見安全漏洞一覽注入注入就是通過給應(yīng)用接口傳入一些特殊字符,達(dá)到欺騙服務(wù)器執(zhí)行惡意的命令。此外,適當(dāng)?shù)臋?quán)限控制不曝露必要的安全信息和日志也有助于預(yù)防注入漏洞。 web 應(yīng)用常見安全漏洞一覽 1. SQL 注入 SQL 注入就是通過給 web 應(yīng)用接口傳入一些特殊字符,達(dá)到欺騙服務(wù)器執(zhí)行惡意的 SQL 命令。 SQL 注入漏洞屬于后端的范疇,但前端也可做體驗(yàn)上的優(yōu)化。 原因 當(dāng)使用外...
摘要:應(yīng)用常見安全漏洞一覽注入注入就是通過給應(yīng)用接口傳入一些特殊字符,達(dá)到欺騙服務(wù)器執(zhí)行惡意的命令。此外,適當(dāng)?shù)臋?quán)限控制不曝露必要的安全信息和日志也有助于預(yù)防注入漏洞。 web 應(yīng)用常見安全漏洞一覽 1. SQL 注入 SQL 注入就是通過給 web 應(yīng)用接口傳入一些特殊字符,達(dá)到欺騙服務(wù)器執(zhí)行惡意的 SQL 命令。 SQL 注入漏洞屬于后端的范疇,但前端也可做體驗(yàn)上的優(yōu)化。 原因 當(dāng)使用外...
摘要:導(dǎo)語智能手機(jī)發(fā)展到今天已經(jīng)有十幾個(gè)年頭,手機(jī)的軟硬件都已經(jīng)發(fā)生了翻天覆地的變化,特別是陣營,從一開始的一兩百到今天動(dòng)輒,內(nèi)存。恰好最近做了內(nèi)存優(yōu)化相關(guān)的工作,這里也對(duì)內(nèi)存優(yōu)化相關(guān)的知識(shí)做下總結(jié)。 導(dǎo)語 智能手機(jī)發(fā)展到今天已經(jīng)有十幾個(gè)年頭,手機(jī)的軟硬件都已經(jīng)發(fā)生了翻天覆地的變化,特別是Android陣營,從一開始的一兩百M(fèi)到今天動(dòng)輒4G,6G內(nèi)存。然而大部分的開發(fā)者觀看下自己的異常上報(bào)系...
閱讀 3132·2021-10-12 10:11
閱讀 1836·2021-08-16 10:59
閱讀 2844·2019-08-30 15:55
閱讀 1223·2019-08-30 14:19
閱讀 2030·2019-08-29 17:03
閱讀 2462·2019-08-29 16:28
閱讀 3212·2019-08-26 13:47
閱讀 2880·2019-08-26 13:36