摘要:關鍵是釋放內存這一步,各種語言都有自己的垃圾回收簡稱機制。用的是這種,在字末位進行標識,為指針。對于而言,最初的垃圾回收機制,是基于引用計次來做的。老生代的垃圾回收,分兩個階段標記清理有和這兩種方式。
不管是高級語言,還是低級語言。內存的管理都是:
分配內存
使用內存(讀或寫)
釋放內存
前兩步,大家都沒有太大異議。關鍵是釋放內存這一步,各種語言都有自己的垃圾回收(garbage collection, 簡稱GC)機制。做GC的第一步是判斷堆中存的是數據還是指針,是指針的話,說明它被指向活躍的對象。有3種判斷方法:
Conservative:如果存儲格式是地址,就認為是。C/C++有用到這種算法。
Compiler hints:對于靜態語言,比如Java,編譯器是知道它是不是指針的,所以可以用這種。
Tagged pointers:JavaScript用的是這種,在字末位進行標識,1為指針。
對于JavaScript而言,最初的垃圾回收機制,是基于引用計次來做的。后來升級為標記清除。
引用計次當對象被引用次數為0時,就被回收。潛在的一個問題是:循環引用時,兩個對象都至少被引用了一次,將不能自動被回收。所以導致,我們常講的內存泄露。
// 引用計次 var a = {t: 1}; // 對象 `{t: 1}` (以下簡稱obj)被引用一次 var b = a; // obj 被引用兩次 a = null; // obj 現在為1次 b = null; // obj 現在為0次,可回收 // 循環引用 function fn() { var a = {}; var b = {}; a.b = b; b.a = a; } fn();標記清除
這是當前主流的GC算法,V8里面就是用這種。當對象,無法從根對象沿著引用遍歷到,即不可達(unreachable),進行清除。對于上面的例子,fn() 里面的 a 和 b 在函數執行完畢后,就不能通過外面的上下文進行訪問了,所以就可以清除了。
下面,我們簡述下V8的GC機制:
V8的GC機制在大部分的應用場景:一個新創建的對象,生命周期通常很短。所以,V8里面,GC處理分為兩大類:新生代和老生代。
新生代的堆空間為1M~8M,而且被平分成兩份(to-space和from-space),通常一個新創建的對象,內存被分配在新生代。當to-space滿的時候,to-space和form-space交換位置(此時,to空,from滿),并執行GC.如果一個對象被斷定為,未被引用,就清除;有被引用,逃逸次數+1(如果此時逃逸次數為2,就移入老生代,否則移入to-space)。
老生代的堆空間大,GC不適合像新生代那樣,用平分成兩個space這種空間換時間的方式。老生代的垃圾回收,分兩個階段:標記、清理(有Sweeping和Compacting這兩種方式)。
標記,采用3色標記:黑、白、灰。步驟如下:
GC開始,所以對象標記為白色。
根對象標記為黑色,并開始遍歷其子節點(引用的對象)。
當前被遍歷的節點,標記為灰色,被放入一個叫 marking bitmap 的棧。在棧中,把當前被遍歷的節點,標記為黑色,并出棧,同時,把它的子節點(如果有的話)標記為灰色,并壓入棧。(大對象比較特殊,這里不展開)
當所有對象被遍歷完后,就只剩下黑和白。通過Sweeping或Compacting的方式,清理掉白色,完成GC。
小補充:JavaScript的根對象GC的時候,從根對象開始遍歷。在瀏覽器,根對象是 window;在 Node.js 中,是 global(或稱為root).
Node.js中,每個文件被當做一個模塊,所以,當你用 var/let/const 在文件的全局,聲明變量的時候,作用域是當前文件(模塊)。因此,圖中 root.a 是 undefined.
Links:Memory Management
What is the root object in Node.js
解讀 V8 GC Log(一): Node.js 應用背景與 GC 基礎知識
解讀 V8 GC Log(二): 堆內外內存的劃分與 GC 算法
A tour of V8: Garbage Collection
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/88482.html
摘要:什么是線程餓死,什么是活鎖多線程中的忙循環是什么變量是什么變量和變量有什么不同類型變量提供什么保證能使得一個非原子操作變成原子操作嗎 JVM專題 showImg(https://segmentfault.com/img/remote/1460000019943435); (面試題+答案領取方式見個人主頁) Java 類加載過程? 描述一下 JVM 加載 Class 文件的原理機制? ...
摘要:還是老規矩,從易到難吧傳統的定時器,異步編程等。分配對象時,先是在空間中進行分配。內存泄漏內存泄漏是指程序中己動態分配的堆內存由于某種原因程序未釋放或無法釋放,造成系統內存的浪費,導致程序運行速度減慢甚至系統崩潰等嚴重后果。 showImg(https://segmentfault.com/img/bVbwkad?w=1286&h=876); 網上參差不棄的面試題,本文由淺入深,讓你在...
摘要:還是老規矩,從易到難吧傳統的定時器,異步編程等。分配對象時,先是在空間中進行分配。內存泄漏內存泄漏是指程序中己動態分配的堆內存由于某種原因程序未釋放或無法釋放,造成系統內存的浪費,導致程序運行速度減慢甚至系統崩潰等嚴重后果。 showImg(https://segmentfault.com/img/bVbwkad?w=1286&h=876); 網上參差不棄的面試題,本文由淺入深,讓你在...
閱讀 3250·2023-04-25 22:47
閱讀 3765·2021-10-11 10:59
閱讀 2300·2021-09-07 10:12
閱讀 4243·2021-08-11 11:15
閱讀 3432·2019-08-30 13:15
閱讀 1750·2019-08-30 13:00
閱讀 968·2019-08-29 14:02
閱讀 1680·2019-08-26 13:57