麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > JavaScript > 正文

JavaScript對內(nèi)存分配及管理機(jī)制詳細(xì)解析

2019-11-20 21:44:42
字體:
供稿:網(wǎng)友

你可能聽說過JAVA、.NET、PHP這些語言有垃圾回收的內(nèi)存管理機(jī)制,但是很少會(huì)聽到JavaScript也有自己的內(nèi)存管理機(jī)制,JavaScript同樣有著類似的垃圾回收功能。本文主要講述了JavaScript的垃圾回收原理和具體的過程。

簡介
在底層語言中,比如C,有專門的內(nèi)存管理機(jī)制,比如malloc() 和 free()。而Javascript是有垃圾回收(garbage collection)機(jī)制的,也就是說JS解釋器會(huì)自動(dòng)分配和回收內(nèi)存。這樣就有人覺得,我用的是高級(jí)語言,就不用關(guān)心內(nèi)存管理了,其實(shí)這是不對的。

內(nèi)存的生命周期
盡管語言不盡相同,而每種語言中內(nèi)存的生命周期都是相似的:

1.當(dāng)需要的時(shí)候分配內(nèi)存
2.對內(nèi)存進(jìn)行讀寫操作
3.當(dāng)上面分配的內(nèi)存不再需要的時(shí)候,將他們釋放掉
對于1,2兩步,幾乎所有語言操作起來都是明確地或者說很直觀,沒什么好說的。而在像Javascript一樣的高級(jí)語言中,第三步操作就顯得不那么直觀。

Javascript中分配內(nèi)存空間
變量初始化
當(dāng)變量初始化的時(shí)候,Javascript會(huì)自動(dòng)分配相應(yīng)的內(nèi)存空間(注:這里MDN上關(guān)于這里用的是Value initialization,到底是聲明,還是在賦值時(shí)候分配空間,還要再學(xué)習(xí)一下)

var n = 123; //  為數(shù)字分配空間
var s = “azerty”; // 字符串

var o = {
a: 1,
b: null
}; // 為對象和它包含的屬性分配內(nèi)存空間

var a = [1, null, "abra"]; // (類似對象)給數(shù)組和它里面的元素分配空間

function f(a){
return a + 2;
} // 為函數(shù)分配空間

//  函數(shù)有時(shí)也會(huì)為分配對象空間
someElement.addEventListener(‘click', function(){
someElement.style.backgroundColor = ‘blue'; //個(gè)人補(bǔ)充,未考證,這里會(huì)為someElement分配空間,如注釋所說,為對象分配空間
}, false);

函數(shù)調(diào)用時(shí)候分配空間
有的函數(shù)調(diào)用,會(huì)產(chǎn)生上面說的那種 為對象分配空間

var d = new Date();
var e = document.createElement('div'); // allocates an DOM element還有下面這種

var s = “azerty”;
var s2 = s.substr(0, 3); // s2 is a new string
// 由于Javascript中字符串是不可變的,所以Javascript也許并沒有為s2中的字符串分配新空間,而是只存了[0, 3]的區(qū)間(用來索引)

var a = ["ouais ouais", "nan nan"];
var a2 = ["generation", "nan nan"];
var a3 = a.concat(a2); // 新的空間來存儲(chǔ)數(shù)組a3

操作變量值
沒什么好說的,讀、寫、函數(shù)調(diào)用。

內(nèi)存不再被使用時(shí),將它們釋放掉
許多內(nèi)存管理機(jī)制的問題都出現(xiàn)在這里。最麻煩的問題是確認(rèn)“這塊內(nèi)存空間已經(jīng)不需要了”。這往往需要程序員告知,這個(gè)程序中,這塊內(nèi)存已經(jīng)不需要了,你們回收吧。

而高級(jí)語言解釋器中嵌入了一個(gè)叫做“垃圾回收(garbage collector)”的工具,用來跟蹤內(nèi)存分配和使用情況,以便在它們不需要的時(shí)候?qū)⑵渥詣?dòng)回收。然而有個(gè)問題,一塊內(nèi)存空間是不是還有用,是具有不確定性的,也就是說,這個(gè)是沒法用算法精確算出來的。

垃圾回收
如上所述原因,垃圾回收機(jī)制采取了一種有限的解決方案來處理上面的不確定性問題。下面介紹集中垃圾回收算法的思想以及相應(yīng)的局限:

引用
這種方法,用到了一種引用的思想。當(dāng)a能訪問A時(shí),就說A引用了a(不論是直接還是間接的)。比如,一個(gè)Javascript對象會(huì)引用他的原型(間接引用)和它的各個(gè)屬性(直接引用)。

這種情形下,對象就被擴(kuò)展的更廣義了,在原生對象的基礎(chǔ)上,還包含了函數(shù)的作用域鏈(或者全局的詞法作用域)。

引用計(jì)數(shù)
這種方法是最拿衣服(naive)的垃圾回收算法。它把“可以回收”的標(biāo)準(zhǔn)定義為“沒有其他人引用這個(gè)對象”(原文:This algorithm reduces the definition of “an object is not needed anymore” to “an object has no other object referencing to it”)。也就是說,只有當(dāng)對象沒有被引用的時(shí)候,才會(huì)被當(dāng)作垃圾回收掉。

舉個(gè)例子
var o = { // 稱之為外層對象
a: { //稱之為內(nèi)層對象
b:2
}
}; //  創(chuàng)建了兩個(gè)對象 內(nèi)層對象作為外層對象的屬性而被引用
// 而外層對象被變量o引用
// 顯然,沒有人會(huì)被垃圾回收

var o2 = o; // o2也引用了上面說的外層對象。好現(xiàn)在外層對象的引用計(jì)數(shù)為‘2' (被o和o2引用)
o = 1; //  現(xiàn)在o不再引用外層對象,只有o2在引用,引用計(jì)數(shù)為 ‘1'

var oa = o2.a; // oa 引用內(nèi)層對象
//  現(xiàn)在內(nèi)層對象同時(shí)被作為外層對象的屬性引用和被oa引用,引用計(jì)數(shù)為‘2'

o2 = “yo”; //  好,現(xiàn)在o2也不引用外層對象了,外層對象引用計(jì)數(shù)為“0”
// 意味著外層對象可以被“垃圾回收”了
// 然而,內(nèi)層對象還被oa引用著,因此還是沒有被回收 (個(gè)人注釋:這里有一點(diǎn)閉包的意味)

oa = null; //  現(xiàn)在oa不引用內(nèi)層對象了
// 內(nèi)層對象也被垃圾回收

局限:循環(huán)引用

看下面代碼:

function f(){
var o = {};
var o2 = {};
o.a = o2; // o 引用 o2
o2.a = o; // o2 引用 o

return “azerty”;
}

f();
// o o2兩個(gè)對象構(gòu)成了循環(huán)引用
// 當(dāng)函數(shù)執(zhí)行完畢的時(shí)候,他們就被關(guān)在了f的作用域里面,沒有外面的人可以使用他們
// 所以按理說,他們已經(jīng)沒有存在價(jià)值了,需要被垃圾回收,釋放內(nèi)存
// 然而,他們的引用計(jì)數(shù)都不為“0”
// 所以在這種引用計(jì)數(shù)的機(jī)制下,他們沒有被回收

實(shí)際例子
在IE6,7版本的瀏覽器中,就是使用的引用計(jì)數(shù)機(jī)制。因此,下面的代碼在IE6,7中可以穩(wěn)穩(wěn)地發(fā)生內(nèi)存泄漏

var div = document.createElement("div");
div.onclick = function(){
  doSomething();
}; // div的onclick屬性,會(huì)引用 function
// 然而這個(gè) function 反過來又引用了這個(gè)div,因?yàn)閐iv在handler的作用域里面。
// 造成上述循環(huán)引用,導(dǎo)致內(nèi)存泄漏。標(biāo)記清除算法

這種算法把“可以回收”定義成“對象不可達(dá)”,即訪問不到。

這種算法,會(huì)定義一個(gè)“根”,并且定期地從“根”出發(fā),找出“根”下面的所有對象,看能不能從“根”找到一條路徑引用到這個(gè)對象。從不同的“根”出發(fā),垃圾回收程序就可以區(qū)分所有對象是不是“不可達(dá)”的,當(dāng)對象“不可達(dá)”時(shí)候,便被回收。

這種算法比引用計(jì)數(shù)算法要好些。因?yàn)?“一個(gè)對象的引用計(jì)數(shù)是0”可以推出“這個(gè)對象不可達(dá)”,逆命題則為假。也就是說這種算法擴(kuò)充了垃圾回收的范圍。

循環(huán)引用不再是困擾
在上面的循環(huán)引用例子中,當(dāng)函數(shù)返回時(shí),o 和 o2都已經(jīng)不再被任何人引用,也就是“不可達(dá)”了,便順理成章地被垃圾回收掉了。

局限:對象需要明確的“不可達(dá)”
雖然說是局限,然而這種情況在實(shí)際當(dāng)中很少發(fā)生,因此很少有人關(guān)注這一點(diǎn)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 国产午夜亚洲精品理论片大丰影院 | 国产1区视频 | 免费毛片观看 | 精品久久久久久亚洲精品 | 午夜国内精品a一区二区桃色 | 精品一区二区三区毛片 | 国产成人强伦免费视频网站 | 玩偶姐姐在线观看免费 | 一级免费看片 | 国产一区二区亚洲 | 久色免费| 久久成人精品视频 | 神马久久精品综合 | 久久无| 成人9禁啪啪无遮挡免费 | 欧洲精品久久久 | 国产在线观看91精品 | 亚洲日本韩国精品 | 91视频久久 | av在线免费观看不卡 | 日本人乱人乱亲乱色视频观看 | 羞羞电影在线观看 | 成人黄色小视频网站 | 好吊色欧美一区二区三区四区 | 激情小说激情图片激情电影 | 国产自91精品一区二区 | 久久精品一区二区三区不卡牛牛 | 国产91小视频在线观看 | 国产一区二区影视 | 视频一区二区精品 | 懂色粉嫩av久婷啪 | 日韩色视频 | 久久久入口 | 免费黄色大片在线观看 | 看毛片的网址 | 久久久久久久久成人 | 久久经典国产视频 | 亚洲天堂成人在线 | 一级国产航空美女毛片内谢 | 国产一级一国产一级毛片 | 日本中文字幕久久 |