JS_垃圾回收機(jī)制

JavaScirpt垃圾回收機(jī)制

垃圾回收.jpg

JavaScript具有自動(dòng)垃圾回收機(jī)制,也就是說枚驻,執(zhí)行環(huán)境會(huì)負(fù)責(zé)管理代碼執(zhí)行過程中使用的內(nèi)存钝凶。

在C和C++中,開發(fā)人員的一項(xiàng)很重要的任務(wù)就是手工跟蹤內(nèi)存的使用情況痹兜,這是造成許多問題的根源。而在JS中颤诀,內(nèi)存的分配實(shí)現(xiàn)了自動(dòng)的管理字旭。

這種垃圾回收機(jī)制的原理其實(shí)很簡單:找出不再繼續(xù)使用的變量,然后釋放其占用的內(nèi)存崖叫。為此遗淳,垃圾收集器會(huì)按照固定的時(shí)間間隔,周期性地執(zhí)行這一操作心傀。

  • 垃圾收集的方式

一屈暗、標(biāo)記清除

這是JS最常用的垃圾收集方式。當(dāng)變量進(jìn)入環(huán)境(eg:在函數(shù)中聲明一個(gè)變量)時(shí),就將它標(biāo)記為“進(jìn)入環(huán)境”养叛。當(dāng)變量離開環(huán)境時(shí)种呐,則將其標(biāo)記為“離開環(huán)境”。

而標(biāo)記的方式有很多種弃甥。比如:像計(jì)算機(jī)組成原理中通過翻轉(zhuǎn)某個(gè)特殊的位爽室,來記錄一個(gè)變量何時(shí)進(jìn)入環(huán)境;或者使用一個(gè)“進(jìn)入/離開環(huán)境的”變量列表來跟蹤哪個(gè)變量發(fā)生了變化淆攻。

垃圾收集器在運(yùn)行的時(shí)候阔墩,會(huì)給存儲(chǔ)在內(nèi)存的所有變量都加上標(biāo)記,然后隨著程序的執(zhí)行瓶珊,慢慢去掉環(huán)境中的變量以及被環(huán)境中變量引用的變量的標(biāo)記啸箫。而在此之后,存有標(biāo)記的變量將被視為準(zhǔn)備刪除的變量伞芹,原因是環(huán)境中的變量已經(jīng)無法訪問到這些變量了筐高。

最后,垃圾收集器完成內(nèi)存清除工作丑瞧,銷毀那些帶標(biāo)記的值柑土,并回收它們所占用的內(nèi)存空間。

目前绊汹,IE稽屏、Firefox、Chrome西乖、Safari和Opera等主流的瀏覽器都使用了標(biāo)記清除式的垃圾收集策略(或類似的策略)狐榔,只不過,垃圾收集的周期略有不同获雕。

堅(jiān)持住薄腻,能看到這行文字,說明你不再是小白了届案。

二庵楷、引用計(jì)數(shù)

這是一種不太常見的垃圾收集策略。簡單地說是跟蹤并記錄每個(gè)值被引用的次數(shù)楣颠。

Netscape Navigator 3.0是最早使用引用計(jì)數(shù)策略的瀏覽器尽纽,但很快它就遇到了一個(gè)嚴(yán)重的問題:循環(huán)引用。(對(duì)象A中包含一個(gè)指針對(duì)象B的指針童漩,而對(duì)象B中也包含一個(gè)指向?qū)ο驛的引用弄贿。)

function problem(){
    var objA = new Object();
    var objB = new Ojbect();
    
    objA.someOtherObject = objB;
    objB.anotherObject = objA;
}

IE9之前的BOMDOM都不是真正的JS對(duì)象,因此存在大量的內(nèi)存泄露現(xiàn)象矫膨。導(dǎo)致循環(huán)引用的情況不止這些差凹,其他情況后面再介紹期奔。

為了避免類似這樣的循環(huán)引用問題,最好是在不使用它們的時(shí)候危尿,將變量設(shè)置為null能庆,切斷變量與它此前引用的值的關(guān)系。

三脚线、性能問題

說到垃圾收集器多長時(shí)間運(yùn)行一次搁胆,不禁讓人聯(lián)想到IE因此聲明狼藉的性能問題。IE的垃圾收集器是根據(jù)內(nèi)存分配量運(yùn)行的邮绿。

具體一點(diǎn)說:就是256個(gè)變量渠旁,4096個(gè)對(duì)象字面量和數(shù)組元素或者64KB的字符串。達(dá)到上述任何一個(gè)值船逮,垃圾收集器就會(huì)運(yùn)行顾腊。很顯然,這種機(jī)制的問題在于挖胃,如果一個(gè)腳本中包含足夠多的變量杂靶,該腳本很可能會(huì)在其生命周期中一直保有那么多的變量。而這樣一來酱鸭,垃圾收集器就不得不頻繁地運(yùn)行吗垮。結(jié)果,由此引發(fā)的嚴(yán)重性能問題促使IE7重寫了垃圾收集機(jī)制凹髓。

事實(shí)上烁登,在有的瀏覽器中可以手動(dòng)觸發(fā)垃圾收集的過程。但通常不建議這么做蔚舀。

在IE中饵沧,調(diào)用window.CollectGarbage();在Opera7以上的版本赌躺,調(diào)用window.opera.collect()方法會(huì)立即執(zhí)行垃圾收集狼牺。

四、管理內(nèi)存

開發(fā)人員一般不必操心內(nèi)存管理的問題礼患,但由于操作系統(tǒng)分配給Web瀏覽器的可用內(nèi)存數(shù)量通常比桌面應(yīng)用程序的少——這樣做的目的主要是出于安全的考慮是钥,目的是防止運(yùn)行網(wǎng)頁時(shí)耗盡系統(tǒng)內(nèi)存而導(dǎo)致系統(tǒng)崩潰。

為了確保占用最少的內(nèi)存讶泰,讓頁面獲得更好的性能咏瑟。力求讓程序在運(yùn)行時(shí),只保存必要的數(shù)據(jù)痪署。一旦數(shù)據(jù)一再有用,最好設(shè)置為null來釋放其引用——這個(gè)做法叫解除引用兄旬。

function createPerson(name){
    var localPerson = name;
    localPerson.name = name;
    return localPerson;
}

var globalPerson = createPerson("learninginto");

//手動(dòng)接觸globalPerson的引用
globalPerson = null;

注意:解除一個(gè)值的引用狼犯,并不意味著自動(dòng)回收該值所占用的內(nèi)存余寥。解除引用的真正作用是讓值脫離執(zhí)行環(huán)境,以便垃圾收集器下次運(yùn)行時(shí)將其回收悯森。

五宋舷、小結(jié)

  • 離開作用域的值,將被自動(dòng)標(biāo)記為可以回收瓢姻,因此將在垃圾收集期間被刪除祝蝠。
  • “標(biāo)記清除”是目前主流的垃圾收集算法。
  • “引用清除”的思想是跟蹤并記錄所有值被引用的次數(shù)幻碱。JS引擎目前都不再使用這種算法绎狭。
  • 當(dāng)代碼中存在循環(huán)引用現(xiàn)象時(shí),“引用計(jì)數(shù)”算法會(huì)導(dǎo)致問題褥傍。
  • 解除變量的引用不僅有助于消除循環(huán)引用現(xiàn)象儡嘶,而且對(duì)垃圾收集也有好處。為了確保有效地回收內(nèi)存恍风,應(yīng)該及時(shí)解除不再使用的全局對(duì)象蹦狂、全局對(duì)象屬性以及循環(huán)引用變量的引用。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末朋贬,一起剝皮案震驚了整個(gè)濱河市凯楔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌锦募,老刑警劉巖啼辣,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異御滩,居然都是意外死亡鸥拧,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門削解,熙熙樓的掌柜王于貴愁眉苦臉地迎上來富弦,“玉大人,你說我怎么就攤上這事氛驮⊥蠊瘢” “怎么了?”我有些...
    開封第一講書人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵矫废,是天一觀的道長盏缤。 經(jīng)常有香客問我,道長蓖扑,這世上最難降的妖魔是什么唉铜? 我笑而不...
    開封第一講書人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮律杠,結(jié)果婚禮上潭流,老公的妹妹穿的比我還像新娘竞惋。我一直安慰自己,他們只是感情好灰嫉,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開白布拆宛。 她就那樣靜靜地躺著,像睡著了一般讼撒。 火紅的嫁衣襯著肌膚如雪浑厚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,682評(píng)論 1 312
  • 那天根盒,我揣著相機(jī)與錄音钳幅,去河邊找鬼。 笑死郑象,一個(gè)胖子當(dāng)著我的面吹牛贡这,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播厂榛,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼盖矫,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了击奶?” 一聲冷哼從身側(cè)響起辈双,我...
    開封第一講書人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎柜砾,沒想到半個(gè)月后湃望,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡痰驱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年证芭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片担映。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡废士,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蝇完,到底是詐尸還是另有隱情官硝,我是刑警寧澤,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布短蜕,位于F島的核電站氢架,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏朋魔。R本人自食惡果不足惜岖研,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望铺厨。 院中可真熱鬧缎玫,春花似錦硬纤、人聲如沸解滓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽洼裤。三九已至邻辉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間腮鞍,已是汗流浹背值骇。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留移国,地道東北人吱瘩。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像迹缀,于是被迫代替她去往敵國和親使碾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容