摘要:例如本地函數的局部變量和參數當前嵌套調用鏈上的其他函數的變量和參數全局變量還有一些其他的,內部的這些值稱為根。例如,如果局部變量中有對象,并且該對象具有引用另一個對象的屬性,則該對象被視為可達性,它引用的那些也是可以訪問的,詳細的例子如下。
最近看到一些面試的回顧,不少有被面試官問到談談JS 垃圾回收機制,說實話,面試官會問這個問題,說明他最近看到一些關于 JS 垃圾回收機制的相關的文章,為了 B 格,就會順帶的問問。
想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等著你!
最近看到一篇講 JS 垃圾回收的國外文章,覺得講得明白,所以就翻譯過來了,希望對你們有所幫助。
垃圾回收JavaScript 中的內存管理是自動執行的,而且是不可見的。我們創建基本類型、對象、函數……所有這些都需要內存。
當不再需要某樣東西時會發生什么? JavaScript 引擎是如何發現并清理它?
可達性JavaScript 中內存管理的主要概念是可達性。
簡單地說,“可達性” 值就是那些以某種方式可訪問或可用的值,它們被保證存儲在內存中。
1. 有一組基本的固有可達值,由于顯而易見的原因無法刪除。例如:
本地函數的局部變量和參數
當前嵌套調用鏈上的其他函數的變量和參數
全局變量
還有一些其他的,內部的
這些值稱為根。
2. 如果引用或引用鏈可以從根訪問任何其他值,則認為該值是可訪問的。
例如,如果局部變量中有對象,并且該對象具有引用另一個對象的屬性,則該對象被視為可達性, 它引用的那些也是可以訪問的,詳細的例子如下。
JavaScript 引擎中有一個后臺進程稱為垃圾回收器,它監視所有對象,并刪除那些不可訪問的對象。
一個簡單的例子下面是最簡單的例子:
// user 具有對象的引用 let user = { name: "John" };
這里箭頭表示一個對象引用。全局變量“user”引用對象 {name:“John”} (為了簡潔起見,我們將其命名為John)。John 的 “name” 屬性存儲一個基本類型,因此它被繪制在對象中。
如果 user 的值被覆蓋,則引用丟失:
user = null;
現在 John 變成不可達的狀態,沒有辦法訪問它,沒有對它的引用。垃圾回收器將丟棄 John 數據并釋放內存。
兩個引用現在讓我們假設我們將引用從 user 復制到 admin:
// user具有對象的引用 let user = { name: "John" }; let admin = user;
現在如果我們做同樣的事情:
user = null;
該對象仍然可以通過 admin 全局變量訪問,所以它在內存中。如果我們也覆蓋admin,那么它可以被釋放。
相互關聯的對象現在來看一個更復雜的例子, family 對象:
function marry (man, woman) { woman.husban = man; man.wife = woman; return { father: man, mother: woman } } let family = marry({ name: "John" }, { name: "Ann" })
函數 marry 通過給兩個對象彼此提供引用來“聯姻”它們,并返回一個包含兩個對象的新對象。
產生的內存結構:
到目前為止,所有對象都是可訪問的。
現在讓我們刪除兩個引用:
delete family.father; delete family.mother.husband;
僅僅刪除這兩個引用中的一個是不夠的,因為所有對象仍然是可訪問的。
但是如果我們把這兩個都刪除,那么我們可以看到 John 不再有傳入的引用:
輸出引用無關緊要。只有傳入的對象才能使對象可訪問,因此,John 現在是不可訪問的,并將從內存中刪除所有不可訪問的數據。
垃圾回收之后:
無法訪問的數據塊有可能整個相互連接的對象變得不可訪問并從內存中刪除。
源對象與上面的相同。然后:
family = null;
內存中的圖片變成:
這個例子說明了可達性的概念是多么重要。
很明顯,John和Ann仍然鏈接在一起,都有傳入的引用。但這還不夠。
“family”對象已經從根上斷開了鏈接,不再有對它的引用,因此下面的整個塊變得不可到達,并將被刪除。
內部算法基本的垃圾回收算法稱為“標記-清除”,定期執行以下“垃圾回收”步驟:
垃圾回收器獲取根并“標記”(記住)它們。
然后它訪問并“標記”所有來自它們的引用。
然后它訪問標記的對象并標記它們的引用。所有被訪問的對象都被記住,以便以后不再訪問同一個對象兩次。
以此類推,直到有未訪問的引用(可以從根訪問)為止。
除標記的對象外,所有對象都被刪除。
例如,對象結構如下:
我們可以清楚地看到右邊有一個“不可到達的塊”。現在讓我們看看“標記并清除”垃圾回收器如何處理它。
第一步標記根
然后標記他們的引用
以及子孫代的引用:
現在進程中不能訪問的對象被認為是不可訪問的,將被刪除:
這就是垃圾收集的工作原理。JavaScript引擎應用了許多優化,使其運行得更快,并且不影響執行。
一些優化:
分代回收——對象分為兩組:“新對象”和“舊對象”。許多對象出現,完成它們的工作并迅速結 ,它們很快就會被清理干凈。那些活得足夠久的對象,會變“老”,并且很少接受檢查。
增量回收——如果有很多對象,并且我們試圖一次遍歷并標記整個對象集,那么可能會花費一些時間,并在執行中會有一定的延遲。因此,引擎試圖將垃圾回收分解為多個部分。然后,各個部分分別執行。這需要額外的標記來跟蹤變化,這樣有很多微小的延遲,而不是很大的延遲。
空閑時間收集——垃圾回收器只在 CPU 空閑時運行,以減少對執行的可能影響。
面試怎么回答1)問什么是垃圾
一般來說沒有被引用的對象就是垃圾,就是要被清除, 有個例外如果幾個對象引用形成一個環,互相引用,但根訪問不到它們,這幾個對象也是垃圾,也要被清除。
2)如何檢垃圾
一種算法是標記 標記-清除 算法,還想說出不同的算法可以參考這里。
更深入一些的講解 http://newhtml.net/v8-garbage...
還有一種牛逼的答法就是說看我的博客,當然是要自己總結的博客。
代碼部署后可能存在的BUG沒法實時知道,事后為了解決這些BUG,花了大量的時間進行log 調試,這邊順便給大家推薦一個好用的BUG監控工具 Fundebug。
你的點贊是我持續分享好東西的動力,歡迎點贊!
交流干貨系列文章匯總如下,覺得不錯點個Star,歡迎 加群 互相學習。
https://github.com/qq44924588...
我是小智,公眾號「大遷世界」作者,對前端技術保持學習愛好者。我會經常分享自己所學所看的干貨,在進階的路上,共勉!
關注公眾號,后臺回復福利,即可看到福利,你懂的。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/102905.html
摘要:原文地址游客前言金三銀四,很多同學心里大概都準備著年后找工作或者跳槽。最近有很多同學都在交流群里求大廠面試題。 最近整理了一波面試題,包括安卓JAVA方面的,目前大廠還是以安卓源碼,算法,以及數據結構為主,有一些中小型公司也會問到混合開發的知識,至于我為什么傾向于混合開發,我的一句話就是走上編程之路,將來你要學不僅僅是這些,豐富自己方能與世接軌,做好全棧的裝備。 原文地址:游客kutd...
摘要:弱引用弱引用比軟引用更弱,被弱引用關聯的對象只能存活到發生下一次垃圾回收之前,也就是說當發生時,無論當前內存是否足夠,都會被回收掉。這是最終的狀態,不能再變為其它狀態。如下圖所示對象都是可被回收的。 【干貨點】看完該篇文章,就基本可以解答面試熱點【談談對Java中幾種引用的理解】了。 大家都知道我公眾號的副業是 showImg(https://segmentfault.com/img/...
摘要:引擎對堆內存中的對象進行分代管理新生代存活周期較短的對象,如臨時變量字符串等。內存泄漏對于持續運行的服務進程,必須及時釋放不再用到的內存。 (關注福利,關注本公眾號回復[資料]領取優質前端視頻,包括Vue、React、Node源碼和實戰、面試指導) 本周正式開始前端進階的第一期,本周的主題是調用堆棧,今天是第4天。 本計劃一共28期,每期重點攻克一個面試重難點,如果你還不了解本進階計劃...
摘要:前段時間,前同事跳槽,機緣巧合下面了阿里,本來憑著試一試的態度,卻不料好事成雙,拿到了,而且薪資也了。面就沒啥東西可聊的,基本上就是對此次面試的一個評價定薪等等一些之內的話題。如果是現場面試,記得關注當天的天氣,提前查一下路線。 ...
閱讀 1974·2021-11-22 19:20
閱讀 2618·2021-11-22 13:54
閱讀 1932·2021-09-04 16:40
閱讀 1814·2021-08-13 11:54
閱讀 2628·2019-08-30 15:55
閱讀 3456·2019-08-29 13:51
閱讀 519·2019-08-29 11:09
閱讀 2997·2019-08-26 14:06