欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript內(nèi)存管理介紹

 更新時(shí)間:2015年03月13日 11:13:07   投稿:junjie  
這篇文章主要介紹了JavaScript內(nèi)存管理介紹,本文講解了內(nèi)存生命周期、JavaScript的內(nèi)存分配、通過(guò)函數(shù)調(diào)用的內(nèi)存分配、當(dāng)內(nèi)存不再需要使用時(shí)釋放等內(nèi)容,需要的朋友可以參考下

簡(jiǎn)介

低級(jí)語(yǔ)言,比如C,有低級(jí)的內(nèi)存管理基元,想malloc(),free()。另一方面,JavaScript的內(nèi)存基元在變量(對(duì)象,字符串等等)創(chuàng)建時(shí)分配,然后在他們不再被使用時(shí)“自動(dòng)”釋放。后者被稱(chēng)為垃圾回收。這個(gè)“自動(dòng)”是混淆并給JavaScript(和其他高級(jí)語(yǔ)言)開(kāi)發(fā)者一個(gè)錯(cuò)覺(jué):他們可以不用考慮內(nèi)存管理。

內(nèi)存生命周期

不管什么程序語(yǔ)言,內(nèi)存生命周期基本一致:

1.分配你所需要的內(nèi)存
2.使用它(讀、寫(xiě))
3.當(dāng)它不被使用時(shí)釋放   ps:和“把大象裝冰箱“一個(gè)意思

第一二部分過(guò)程在所有語(yǔ)言中都很清晰。最后一步在低級(jí)語(yǔ)言中很清晰,但是在像JavaScript等高級(jí)語(yǔ)言中,最后一步不清晰。

JavaScript的內(nèi)存分配

變量初始化

為了不讓程序員為分配費(fèi)心,JavaScript在定義變量時(shí)完成內(nèi)存分配。

復(fù)制代碼 代碼如下:

var n = 123; // 給數(shù)值變量分配內(nèi)存
var s = "azerty"; // 給字符型

var o = {
  a: 1,
  b: null
}; // 為對(duì)象及其包含變量分配內(nèi)存

var a = [1, null, "abra"]; // 為數(shù)組及其包含變量分配內(nèi)存(就像對(duì)象)
function f(a){
  return a + 2;
} // 為函數(shù)(可調(diào)用的對(duì)象)分配內(nèi)存

// 函數(shù)表達(dá)式也能分配一個(gè)對(duì)象
someElement.addEventListener('click', function(){
  someElement.style.backgroundColor = 'blue';
}, false);

通過(guò)函數(shù)調(diào)用的內(nèi)存分配

有些函數(shù)調(diào)用結(jié)果是分配對(duì)象內(nèi)存:

復(fù)制代碼 代碼如下:

var d = new Date();
var e = document.createElement('div'); //分配一個(gè)DOM元素

有些方法分配新變量或者新對(duì)象:

復(fù)制代碼 代碼如下:

var s = "azerty";
var s2 = s.substr(0, 3); // s2 is a new string
//因?yàn)閟tring是不變量,JavaScript可能沒(méi)有分配內(nèi)存,但只是存儲(chǔ)了0-3的范圍。

var a = ["ouais ouais", "nan nan"];
var a2 = ["generation", "nan nan"];
var a3 = a.concat(a2); // 新數(shù)組中有連接數(shù)組a和數(shù)組a2中的四個(gè)元素。

值的使用

使用值的過(guò)程實(shí)際上是對(duì)分配內(nèi)存進(jìn)行讀取與寫(xiě)入的操作,這意味著可以寫(xiě)入一個(gè)變量或者一個(gè)對(duì)象的屬性值,甚至傳遞函數(shù)的參數(shù)。

當(dāng)內(nèi)存不再需要使用時(shí)釋放

大多數(shù)內(nèi)存管理的問(wèn)題都在這個(gè)階段。在這里最艱難的任務(wù)是找到“所分配的內(nèi)存確實(shí)已經(jīng)不再需要了”。它往往要求開(kāi)發(fā)人員來(lái)確定在程序中哪一塊內(nèi)存不再需要并且釋放它。

高級(jí)語(yǔ)言解釋器嵌入了“垃圾回收器”,主要工作是跟蹤內(nèi)存的分配和使用,以便當(dāng)分配的內(nèi)存不再使用時(shí),自動(dòng)釋放它。這個(gè)過(guò)程是一個(gè)近似的,因?yàn)橐滥硥K內(nèi)存是否需要是 無(wú)法判定的 (無(wú)法被某種算法所解決).

垃圾回收

如上文所述自動(dòng)尋找是否一些內(nèi)存“不再需要”的問(wèn)題是無(wú)法判定的。因此,垃圾回收實(shí)現(xiàn)只能有限制的解決一般問(wèn)題。本節(jié)將解釋必要的概念,了解主要的垃圾回收算法和它們的局限性。

引用

垃圾回收算法主要依賴(lài)于引用的概念。在內(nèi)存管理的環(huán)境中,一個(gè)對(duì)象如果有訪(fǎng)問(wèn)另一個(gè)對(duì)象的權(quán)限(隱式或者顯式),叫做一個(gè)對(duì)象引用另一個(gè)對(duì)象。例如,一個(gè)Javascript對(duì)象具有對(duì)它 原型 的引用(隱式引用)和對(duì)它屬性的引用(顯式引用)。

在這里,“對(duì)象”的概念不僅特制Javascript對(duì)象,還包括函數(shù)作用域(或者全局詞法作用域)。

引用計(jì)數(shù)垃圾收集

這是最簡(jiǎn)單的垃圾收集算法。此算法把“對(duì)象是否不再需要”簡(jiǎn)化定義為“對(duì)象有沒(méi)有其他對(duì)象引用到它”。如果沒(méi)有引用指向該對(duì)象(零引用),對(duì)象將被垃圾回收機(jī)制回收。

例如

復(fù)制代碼 代碼如下:

var o = {
  a: {
    b:2
  }
};
// 兩個(gè)對(duì)象被創(chuàng)建,一個(gè)做為另一個(gè)的屬性被引用,另一個(gè)被分配給變量o
// 很顯然,沒(méi)有一個(gè)可以被垃圾收集

var o2 = o; // o2變量是第二個(gè)對(duì)“這個(gè)對(duì)象”的引用
o = 1; // 現(xiàn)在,“這個(gè)對(duì)象”的原始引用o被o2替換了

var oa = o2.a; // 引用“這個(gè)對(duì)象”的a屬性
// 現(xiàn)在,“這個(gè)對(duì)象”有兩個(gè)引用了,一個(gè)是o2,一個(gè)是oa

o2 = "yo"; // 最初的對(duì)象現(xiàn)在已經(jīng)是零引用了
// 他可以被垃圾回收了
// 然而它的屬性a的對(duì)象還在被oa引用,所以還不能回收

oa = null; // a屬性的那個(gè)對(duì)象現(xiàn)在也是零引用了
// 它可以被垃圾回收了

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

這個(gè)簡(jiǎn)單的算法有一個(gè)限制,就是如果一個(gè)對(duì)象引用另一個(gè)(形成了循環(huán)引用),他們可能“不再需要”了,但是他們不會(huì)被回收。

復(fù)制代碼 代碼如下:

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

  return "azerty";
}

f();
// 兩個(gè)對(duì)象被創(chuàng)建,并互相引用,形成了一個(gè)循環(huán)
// 他們被調(diào)用之后不會(huì)離開(kāi)函數(shù)作用域
// 所以他們已經(jīng)沒(méi)有用了,可以被回收了
// 然而,引用計(jì)數(shù)算法考慮到他們互相都有至少一次引用,所以他們不會(huì)被回收

實(shí)際當(dāng)中的例子

IE 6, 7 對(duì)DOM對(duì)象進(jìn)行引用計(jì)數(shù)回收。對(duì)他們來(lái)說(shuō),一個(gè)常見(jiàn)問(wèn)題就是內(nèi)存泄露:

復(fù)制代碼 代碼如下:

var div = document.createElement("div");
div.onclick = function(){
  doSomething();
};
// div有了一個(gè)引用指向事件處理屬性onclick
// 事件處理也有一個(gè)對(duì)div的引用可以在函數(shù)作用域中被訪(fǎng)問(wèn)到
// 這個(gè)循環(huán)引用會(huì)導(dǎo)致兩個(gè)對(duì)象都不會(huì)被垃圾回收

標(biāo)記-清除算法

這個(gè)算法把“對(duì)象是否不再需要”簡(jiǎn)化定義為“對(duì)象是否可以獲得”。

這個(gè)算法假定設(shè)置一個(gè)叫做根的對(duì)象(在Javascript里,根是全局對(duì)象)。定期的,垃圾回收器將從根開(kāi)始,找所有從根開(kāi)始引用的對(duì)象,然后找這些對(duì)象引用的對(duì)象……從根開(kāi)始,垃圾回收器將找到所有可以獲得的對(duì)象和所有不能獲得的對(duì)象。

這個(gè)算法比前一個(gè)要好,因?yàn)椤坝辛阋玫膶?duì)象”總是不可獲得的,但是相反卻不一定,參考“循環(huán)引用”。

從2012年起,所有現(xiàn)代瀏覽器都使用了標(biāo)記-清除垃圾回收算法。所有對(duì)JavaScript垃圾回收算法的改進(jìn)都是基于標(biāo)記-清除算法的改進(jìn),并沒(méi)有改進(jìn)標(biāo)記-清除算法本身和它對(duì)“對(duì)象是否不再需要”的簡(jiǎn)化定義。

循環(huán)引用不再是問(wèn)題了

在上面的示例中,函數(shù)調(diào)用返回之后,兩個(gè)對(duì)象從全局對(duì)象出發(fā)無(wú)法獲取。因此,他們將會(huì)被垃圾回收器回收。
第二個(gè)示例同樣,一旦 div 和其事件處理無(wú)法從根獲取到,他們將會(huì)被垃圾回收器回收。

限制: 對(duì)象需要明確的不可獲得

盡管這是一個(gè)限制,但是很少會(huì)被突破,這也就是為什么在現(xiàn)實(shí)中很少人會(huì)去關(guān)心垃圾回收機(jī)制。

相關(guān)文章

  • JS基礎(chǔ)之邏輯結(jié)構(gòu)與循環(huán)操作示例

    JS基礎(chǔ)之邏輯結(jié)構(gòu)與循環(huán)操作示例

    這篇文章主要介紹了JS基礎(chǔ)之邏輯結(jié)構(gòu)與循環(huán)操作,結(jié)合實(shí)例形式分析了JavaScript邏輯判斷、流程控制、循環(huán)語(yǔ)句等相關(guān)操作技巧,需要的朋友可以參考下
    2020-01-01
  • javascript常用經(jīng)典算法實(shí)例詳解

    javascript常用經(jīng)典算法實(shí)例詳解

    這篇文章主要介紹了javascript常用算法,結(jié)合實(shí)例形式較為詳細(xì)的分析總結(jié)了JavaScript中常見(jiàn)的各種排序算法以及堆、棧、鏈表等數(shù)據(jù)結(jié)構(gòu)的相關(guān)實(shí)現(xiàn)與使用技巧,需要的朋友可以參考下
    2015-11-11
  • js實(shí)現(xiàn)左右輪播圖

    js實(shí)現(xiàn)左右輪播圖

    這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)左右輪播圖,實(shí)現(xiàn)手動(dòng)和自動(dòng)兩種方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-01-01
  • 不唐突的JavaScript的七條準(zhǔn)則整理收集

    不唐突的JavaScript的七條準(zhǔn)則整理收集

    在開(kāi)始設(shè)計(jì)你的腳本之前,要考慮的第一件事情就是檢查一下你要為其編寫(xiě)腳本的HTML代碼,看看有什么東西可以幫助你達(dá)到目的。
    2008-10-10
  • javascript實(shí)現(xiàn)滾輪輪播圖片

    javascript實(shí)現(xiàn)滾輪輪播圖片

    這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)滾輪輪播圖片,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • 解決layer.confirm快速點(diǎn)擊會(huì)重復(fù)觸發(fā)事件的問(wèn)題

    解決layer.confirm快速點(diǎn)擊會(huì)重復(fù)觸發(fā)事件的問(wèn)題

    今天小編就為大家分享一篇解決layer.confirm快速點(diǎn)擊會(huì)重復(fù)觸發(fā)事件的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-09-09
  • JS 毫秒轉(zhuǎn)時(shí)間示例代碼

    JS 毫秒轉(zhuǎn)時(shí)間示例代碼

    毫秒轉(zhuǎn)時(shí)間的方法有很多,在本文將為大家介紹下js中是如何實(shí)現(xiàn)的,感興趣的朋友可以參考下
    2013-09-09
  • JavaScript實(shí)現(xiàn)左右滾動(dòng)電影畫(huà)布

    JavaScript實(shí)現(xiàn)左右滾動(dòng)電影畫(huà)布

    這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)左右滾動(dòng)電影畫(huà)布,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • js調(diào)用本地exe程序的兩種方式小結(jié)

    js調(diào)用本地exe程序的兩種方式小結(jié)

    這篇文章主要介紹了js調(diào)用本地exe程序的兩種方式小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • YUI Compressor壓縮JavaScript原理及微優(yōu)化

    YUI Compressor壓縮JavaScript原理及微優(yōu)化

    最近寫(xiě)一個(gè)jQuery插件,在最后完成優(yōu)化時(shí),對(duì)比發(fā)現(xiàn)壓縮后文件比較大,就思考那些是可以被修改和優(yōu)化的,發(fā)現(xiàn)壓縮原理也有很大的空間可以學(xué)習(xí)
    2013-01-01

最新評(píng)論