2019-12-17:第四章:垃圾回收,內(nèi)存管理殖属,小結(jié)

2.1作用域增長

with和try-catch語句可以在作用域鏈的前端添加新的變量對象姐叁。當(dāng)執(zhí)行流進(jìn)入with或者try-catch語句時,系統(tǒng)會在作用域鏈頂端增加臨時的變量對象洗显,直至try-catch語句或with語句執(zhí)行結(jié)束外潜,系統(tǒng)銷毀作用域鏈頂端的臨時變量對象。

對于with語句墙懂,系統(tǒng)會將with指定的對象加入頂端的臨時變量對象中橡卤。

在這個例子中,with語句接受的是location對象

這個增加的變量對象擁有所有l(wèi)ocation對象中包含的屬性和方法损搬,其實(shí)在對url進(jìn)行命名時碧库,系統(tǒng)首先從with變量對象中找到了location.href,又在外層的buildUrl變量對象里找到了qs的值巧勤,將二者相加嵌灰。這就是標(biāo)準(zhǔn)的標(biāo)識符解析過程。

2.2沒有塊級作用域

需要注意的是颅悉,js和絕大多數(shù)語言不同沽瞭,他不是以大括號形成的語句塊來區(qū)分作用域的,在我們常見的if,for語句中定義的變量剩瓶,只要是在同一個函數(shù)(同一個作用域)內(nèi)驹溃,則即便for語句和if語句執(zhí)行完成城丧,變量也不會被銷毀,這點(diǎn)非常重要豌鹤。

可以發(fā)現(xiàn)亡哄,塊中定義的變量在塊運(yùn)行結(jié)束后仍然存在,沒有被回收

因此一定要注意布疙,尤其是在for語句中蚊惯,被定義的循環(huán)變量在運(yùn)行結(jié)束后不會被銷毀。而是繼續(xù)存在于它所處的作用域的變量對象中灵临。

聲明變量截型。當(dāng)使用var來聲明變量時,一般情況下會將變量添加到最近的函數(shù)環(huán)境的變量對象中儒溉。在函數(shù)內(nèi)部宦焦,就是函數(shù)環(huán)境。如果在沒有使用var來聲明顿涣,則該變量默認(rèn)為全局變量赶诊。

a是函數(shù)fun環(huán)境內(nèi)變量對象的值,外部無法訪問园骆,而b是全局對象,在外部可以訪問

查詢標(biāo)識符的過程寓调。如昨天我的插圖所示:

標(biāo)識符解析過程

3.垃圾收集

js中的垃圾回收機(jī)制是自動垃圾回收锌唾。即系統(tǒng)自動判斷哪些變量已經(jīng)沒有用處,可以銷毀釋放內(nèi)存夺英。時下幾乎全部流行語言都擁有自動垃圾回收的機(jī)制晌涕。這使得開發(fā)人員不必像在使用C/C++時,需要人工地跟蹤變量的內(nèi)存占用情況痛悯,并且在必要的時刻釋放變量所占取的內(nèi)存余黎。

自動垃圾回收的基本原理非常簡單:找出不再被使用的變量 - > 周期性回收這些不會再被使用的變量,釋放對應(yīng)內(nèi)存载萌。

簡單解釋以下一個變量從被聲明到被銷毀的聲明周期:

當(dāng)一個變量在環(huán)境內(nèi)被聲明后惧财,其在棧內(nèi)存中得到相應(yīng)的內(nèi)存分配。函數(shù)執(zhí)行過程中扭仁,變量被使用垮衷。當(dāng)環(huán)境內(nèi)所有的語句執(zhí)行結(jié)束后,變量被打上可以銷毀的標(biāo)記乖坠,當(dāng)垃圾回收的任務(wù)周期性啟動時搀突,他會回收所有被打上可銷毀標(biāo)記的變量。但這是最理想的情況熊泵,實(shí)際操作起來遠(yuǎn)比這復(fù)雜的多仰迁。標(biāo)記無用變量是一個很復(fù)雜的流程甸昏。

在標(biāo)記無用變量這個問題里,核心是兩個:1.標(biāo)記策略徐许,2.標(biāo)記方法施蜜。對于開發(fā)人員來說,必須掌握常見的標(biāo)記策略绊寻,而實(shí)際的標(biāo)記方法知道原理即可花墩。

3.1標(biāo)記清除

標(biāo)記清除是js最常用的標(biāo)記策略。

當(dāng)一個變量進(jìn)入環(huán)境時(例如在函數(shù)中被聲明)澄步,該變量被標(biāo)記上‘進(jìn)入環(huán)境’的標(biāo)記冰蘑。理論上講,任何被標(biāo)記為'進(jìn)入環(huán)境'的變量都不能被清除村缸,因?yàn)榄h(huán)境很可能使用他們祠肥。當(dāng)一個變量離開環(huán)境時(函數(shù)執(zhí)行完畢),該變量被標(biāo)記上‘離開環(huán)境’的標(biāo)記梯皿。

標(biāo)記的方法有很多種仇箱,使用一個列表記錄,或者翻轉(zhuǎn)變量的某個特殊的位來進(jìn)行標(biāo)記东羹,總之標(biāo)記的方法五花八門各種各樣剂桥。但是i正如上文所說,這些都不重要属提,重要的是策略权逗。

3.2引用計(jì)數(shù)

引用計(jì)數(shù)說白了就是計(jì)算有多少個變量指向同一個對象。當(dāng)有大于一個引用類型的變量指向一個對象時冤议,說明該對象有效斟薇,可以被訪問。而當(dāng)沒有任何引用類型的變量指向一個對象時恕酸,說明該對象已經(jīng)無法被訪問堪滨,因此可以銷毀釋放內(nèi)存。

舉例說明:當(dāng)定義一個變量A指向一個對象object時蕊温,這個object的引用計(jì)數(shù) = 1袱箱,如果此時定義一個變量B = A,則這個object的引用計(jì)數(shù) = 1+1义矛,如果此時將A與B分別重新指向object1和object2犯眠,那么object的引用計(jì)數(shù) = 2-1-1 = 0,此時object再也無法被訪問症革,因此可以標(biāo)記筐咧。當(dāng)下次垃圾收集job執(zhí)行時,object對象就會被銷毀。

但是引用計(jì)數(shù)里存在一個嚴(yán)重的BUG量蕊,即引用循環(huán):

a與b的引用計(jì)數(shù)永遠(yuǎn)不可能是0

假如如圖所示的情況在某個函數(shù)中存在铺罢,而這個函數(shù)又被大量復(fù)用,那么該函數(shù)每運(yùn)行一次残炮,就會有兩個變量無法銷毀韭赘,即由此就會產(chǎn)生嚴(yán)重的內(nèi)存泄露問題。

當(dāng)代雖然絕大多數(shù)瀏覽器都放棄了引用計(jì)數(shù)而完全使用標(biāo)記清除的策略势就,但這種隱患仍然需要重視泉瞻,因?yàn)檫@個問題真實(shí)存在于現(xiàn)實(shí)的工程開發(fā)過程里:在IE9以前的瀏覽器里,其BOM于DOM對象是基于C+COM對象的形式來實(shí)現(xiàn)的苞冯,而COM對象的垃圾回收策略就使用的是引用計(jì)數(shù)袖牙,換句話說,只要IE中涉及到COM對象的地方舅锄,就可能存在內(nèi)存泄漏鞭达。

僅在IE9以下內(nèi)可能存在

3.3垃圾回收的性能問題

因?yàn)槔厥帐且粋€周期性運(yùn)行的過程,因此定義其運(yùn)行周期是一個值得思考的問題皇忿。在古老版本的IE(7以前)系統(tǒng)里畴蹭,IE采取的是臨界值啟動的方式,即當(dāng)且僅當(dāng)內(nèi)存中存在 256個變量 || 4096個對象或數(shù)組字面量和數(shù)組元素 || 64KB的字符串時鳍烁,啟動垃圾回收叨襟。可這帶來一個巨大的問題:即如果這些變量大多都定義在全局變量中的話幔荒,則垃圾回收機(jī)制將被被頻繁地啟動芹啥,而這將極大地影響瀏覽器的性能。

IE7以后铺峭,垃圾回收機(jī)制得到了重寫,使得這個臨界值得以動態(tài)修正汽纠。

簡單描述:回收的少卫键,臨界值翻倍;回收地多虱朵,臨界值歸位

3.4內(nèi)存管理

盡管js有自動垃圾回收機(jī)制莉炉。但是我們在實(shí)際書寫代碼地過程中最好養(yǎng)成手工釋放變量的好習(xí)慣。這是因?yàn)閷?shí)際上碴犬,系統(tǒng)分配給瀏覽器的內(nèi)存一般遠(yuǎn)少于桌面應(yīng)用程序絮宁,目的是防止瀏覽器吃盡系統(tǒng)內(nèi)存而導(dǎo)致系統(tǒng)崩潰。而瀏覽器得到的有限內(nèi)存則會影響變量分配服协,調(diào)用棧绍昂,以及在一個棧內(nèi)可以運(yùn)行的語句數(shù)量。因此我們推薦在實(shí)際書寫代碼中,對于不再使用的變量窘游,我們應(yīng)該手工釋放其內(nèi)存唠椭。

簡單來說,就是對象數(shù)據(jù)如果不再用了忍饰,就把他的值設(shè)置為null贪嫂。即解除引用。

在這個過程里艾蓝,函數(shù)內(nèi)的對象localPerson因?yàn)楹瘮?shù)執(zhí)行結(jié)束后就將離開環(huán)境力崇,因此無需我們手工解除引用,而全局的globalPerson則需要我們手工解除

但是仍然需要說明的一點(diǎn)是赢织,解除引用不代表釋放內(nèi)存亮靴。解除引用的實(shí)質(zhì)是為這個變量打上可以回收的標(biāo)記,方便自動垃圾回收機(jī)制回收他們敌厘。

4.小結(jié)

① js的變量類型分兩類:基本類型和引用類型台猴,基本類型有五種:boolean,string俱两,number饱狂,null,undefined宪彩。

② 基本類型在內(nèi)存中占據(jù)固定大小休讳,保存在棧內(nèi)存中。

③ 從一個變量復(fù)制一個變量尿孔,是創(chuàng)建該值的副本(引用復(fù)制引用俊柔,基本類型復(fù)制基本類型)

④ 引用類型的值實(shí)質(zhì)上一個指針,它指向內(nèi)存中的某個對象活合。

⑤ 復(fù)制引用類型實(shí)際上是復(fù)制一根指向相同對象的指針雏婶。

⑥ 確定基本值類型可以使用typeof(),確定引用類型可以使用instanceof()。

⑦ 所有引用類型都存儲在執(zhí)行環(huán)境(又稱作用域)中白指,它控制著變量的生命周期留晚,以及訪問數(shù)據(jù)的權(quán)限。

⑧ 執(zhí)行環(huán)境分為全局環(huán)境與函數(shù)環(huán)境告嘲。

⑨ 每次進(jìn)入一個新的執(zhí)行環(huán)境則會創(chuàng)建一個新的作用域鏈错维,用于搜索語句中需要的變量和函數(shù)(由內(nèi)向外)

⑨ 變量的執(zhí)行環(huán)境有助于垃圾回收。

⑩ 離開作用域的值會被標(biāo)記上可以回收的標(biāo)記橄唬。

11. 離開作用域的值會被垃圾回收機(jī)制回收

12. 兩種垃圾回收策略:標(biāo)記清除 和 引用計(jì)數(shù)赋焕。

13. 在引用計(jì)數(shù)策略中,循環(huán)引用會導(dǎo)致內(nèi)存泄漏(垃圾回收機(jī)制失效)

14. 隨時手工解除不再使用的對象的引用(把引用類型的變量設(shè)為null)是個好好好好好習(xí)慣仰楚!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末隆判,一起剝皮案震驚了整個濱河市犬庇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蜜氨,老刑警劉巖械筛,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異飒炎,居然都是意外死亡埋哟,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進(jìn)店門郎汪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赤赊,“玉大人,你說我怎么就攤上這事煞赢∨准疲” “怎么了?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵照筑,是天一觀的道長吹截。 經(jīng)常有香客問我,道長凝危,這世上最難降的妖魔是什么波俄? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮蛾默,結(jié)果婚禮上懦铺,老公的妹妹穿的比我還像新娘。我一直安慰自己支鸡,他們只是感情好冬念,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著牧挣,像睡著了一般急前。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瀑构,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天裆针,我揣著相機(jī)與錄音,去河邊找鬼检碗。 笑死,一個胖子當(dāng)著我的面吹牛码邻,可吹牛的內(nèi)容都是我干的折剃。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼像屋,長吁一口氣:“原來是場噩夢啊……” “哼怕犁!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤奏甫,失蹤者是張志新(化名)和其女友劉穎戈轿,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體阵子,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡思杯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了挠进。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片色乾。...
    茶點(diǎn)故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖领突,靈堂內(nèi)的尸體忽然破棺而出暖璧,到底是詐尸還是另有隱情,我是刑警寧澤君旦,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布澎办,位于F島的核電站,受9級特大地震影響金砍,放射性物質(zhì)發(fā)生泄漏局蚀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一捞魁、第九天 我趴在偏房一處隱蔽的房頂上張望至会。 院中可真熱鬧,春花似錦谱俭、人聲如沸奉件。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽县貌。三九已至,卻和暖如春凑懂,著一層夾襖步出監(jiān)牢的瞬間煤痕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工接谨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留摆碉,地道東北人。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓脓豪,卻偏偏與公主長得像巷帝,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子扫夜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評論 2 355

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