最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時間:2013年11月11日 09:55:16   作者:  
本文主要講述了JavaScript的垃圾回收原理和具體的過程。需要的朋友可以過來參考下,希望對大家有所幫助

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

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

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

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

Javascript中分配內(nèi)存空間
變量初始化
當(dāng)變量初始化的時候,Javascript會自動分配相應(yīng)的內(nèi)存空間(注:這里MDN上關(guān)于這里用的是Value initialization,到底是聲明,還是在賦值時候分配空間,還要再學(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ù)有時也會為分配對象空間
someElement.addEventListener(‘click', function(){
someElement.style.backgroundColor = ‘blue'; //個人補充,未考證,這里會為someElement分配空間,如注釋所說,為對象分配空間
}, false);

函數(shù)調(diào)用時候分配空間
有的函數(shù)調(diào)用,會產(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); // 新的空間來存儲數(shù)組a3

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

相關(guān)文章

  • 詳解JavaScript中的blink()方法的使用

    詳解JavaScript中的blink()方法的使用

    這篇文章主要介紹了詳解JavaScript中的blink()方法的使用,是JS入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-06-06
  • js中不同的height, top的區(qū)別對比

    js中不同的height, top的區(qū)別對比

    今天特地花了一點時間整理了下height, top的區(qū)別,本篇主要以chrome為準(zhǔn),可能各個瀏覽器之間還是有一些區(qū)別,需要的朋友可以參考下
    2015-09-09
  • 簡述JavaScript的正則表達(dá)式中test()方法的使用

    簡述JavaScript的正則表達(dá)式中test()方法的使用

    這篇文章主要介紹了簡述JavaScript的正則表達(dá)式中test()方法的使用,是JS入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-06-06
  • JavaScript 事件對象介紹

    JavaScript 事件對象介紹

    這篇文章主要介紹了JavaScript 事件對象介紹,需要的朋友可以參考下
    2015-04-04
  • Websocket協(xié)議詳解及簡單實例代碼

    Websocket協(xié)議詳解及簡單實例代碼

    這篇文章主要介紹了Websocket協(xié)議詳解及簡單實例代碼的相關(guān)資料,這里對websocket 協(xié)議進(jìn)行詳細(xì)介紹,并附簡單實例代碼,需要的朋友可以參考下
    2016-12-12
  • 簡介JavaScript中的italics()方法的使用

    簡介JavaScript中的italics()方法的使用

    這篇文章主要介紹了JavaScript中的italics()方法使用,是JS入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-06-06
  • JavaScript基礎(chǔ)教程——入門必看篇

    JavaScript基礎(chǔ)教程——入門必看篇

    下面小編就為大家?guī)硪黄狫avaScript基礎(chǔ)教程——入門必看篇。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-05-05
  • javascript中判斷一個值是否在數(shù)組中并沒有直接使用

    javascript中判斷一個值是否在數(shù)組中并沒有直接使用

    在JS中要判斷一個值是否在數(shù)組中并沒有函數(shù)直接使用,如PHP中就有in_array()這個函數(shù),可以寫一個類似in_array()函數(shù)功能的方法
    2012-12-12
  • js中document.write的那點事

    js中document.write的那點事

    document.write()方法可以用在兩個方面:頁面載入過程中用實時腳本創(chuàng)建頁面內(nèi)容,以及用延時腳本創(chuàng)建本窗口或新窗口的內(nèi)容。該方法需要一個字符串參數(shù),它是寫到窗口或框架中的HTML內(nèi)容。這些字符串參數(shù)可以是變量或值為字符串的表達(dá)式,寫入的內(nèi)容常常包括HTML標(biāo)記語言
    2014-12-12
  • 12種不宜使用的Javascript語法整理

    12種不宜使用的Javascript語法整理

    Javascript語法,初學(xué)js的朋友都應(yīng)該知道,下面整理了12種不宜使用的js語法,感興趣的朋友可以參考下
    2013-11-11

最新評論

芦溪县| 柏乡县| 红安县| 高唐县| 吉木乃县| 武功县| 伊川县| 永兴县| 武城县| 昭苏县| 佛学| 万宁市| 灌阳县| 独山县| 锦州市| 乌兰浩特市| 德清县| 额敏县| 蓝田县| 石嘴山市| 河间市| 论坛| 西安市| 岑巩县| 巫溪县| 吉木乃县| 铁力市| 班玛县| 华宁县| 壤塘县| 华安县| 开原市| 罗源县| 肇庆市| 融水| 体育| 昌都县| 吉木乃县| 瑞金市| 肇州县| 绥中县|