摘要:一內(nèi)存生命周期分配需要的內(nèi)存初始化值時使用分配的內(nèi)存不需要時將其內(nèi)存釋放垃圾回收器注意全局變量的生命周期直至瀏覽器卸載頁面才會結(jié)束。
一、內(nèi)存生命周期
1、分配需要的內(nèi)存(初始化值時)
2、使用分配的內(nèi)存
3、不需要時將其內(nèi)存釋放(垃圾回收器)
注意:
(1)全局變量的生命周期直至瀏覽器卸載頁面才會結(jié)束。
(2)局部變量只在函數(shù)的執(zhí)行過程中存在,而在這個過程中會為局部變量在?;蚨焉戏峙湎鄳?yīng)的空間,以存儲它們的值,然后再函數(shù)中使用這些變量直至函數(shù)結(jié)束局部變量就沒有存在必要了,可以釋放它們占用的內(nèi)存
(1)算法原理
通過在對象頭中分配一個空間來保存該對象被引用的次數(shù)。如果該對象被其它對象引用,則它的引用計數(shù)加一,如果刪除對該對象的引用,那么它的引用計數(shù)就減一,當該對象的引用計數(shù)為0時,那么該對象就會被回收。
(2)算法理解
var p = new String("abc"); // 分配所需內(nèi)存并且被p引用 abc這個字符串對象的引用計數(shù)值為1.
p = null; // 去除abc字符串對象的引用,abc字符串對象的引用計數(shù)減1
重點理解
1、當對象的引用發(fā)生變化時,首先對原來引用對象的計數(shù)減一,再對新的引用對象的計數(shù)加一
var p = new String("abc"); var q = new String("efd"); p = q;
2、當某個對象的引用計數(shù)減為0時,collector需要遞歸遍歷它所指向的所有域,將它所有域所指向的對象的引用計數(shù)都減一,然后才能回收當前對象。在遞歸過程中,引用計數(shù)為0的對象也都將被回收,并把該對象的內(nèi)存塊加入空閑鏈表中
var p = { phone:new String("1592xxxx"), address:new String("1130 kifer rd") } p = null;
3、循環(huán)引用
function f(){ var o = {}; var o2 = {}; o.a = o2; // o 引用 o2 o2.a = o; // o2 引用 o return "azerty"; } f();
(3)觸發(fā)時機
引用計數(shù)垃圾收集機制在引用計數(shù)變化為0時即刻發(fā)生,而且只針對某一個對象以及它所依賴的其它對象。所以,我們一般也稱呼引用計數(shù)垃圾收集為直接的垃圾收集機制
(1)算法原理
這個算法把“對象是否不再需要”簡化定義為“對象是否可以獲得”。
標記階段是把所有活動對象都做上標記的階段。清除階段是把那些沒有標記的對象,也就是非活動對象回收的階段。通過這兩個階段,就可以令不能利用的內(nèi)存空間重新得到利用
這個算法假定設(shè)置一個叫做根(root)的對象(在Javascript里,根是全局對象)。垃圾回收器將定期從根開始,找所有從根開始引用的對象,然后找這些對象引用的對象……從根開始,垃圾回收器將找到所有可以獲得的對象和收集所有不能獲得的對象。
(2)算法理解
var teacher = {name:"Mary",age:35}; var student = { stu1:{name:"Amy",age:13}, stu2:{name:"Dai",age:15} }
標記階段
// 標記階段偽代碼 // 進行標記階段的處理 mark_phase(){ for(r : $roots) mark(*r) } // 遞歸地標記通過指針數(shù)組能訪問到的對象。這樣就能把所有活動對象都標記上了。 mark(obj){ if(obj.mark == FALSE) obj.mark = TRUE for(child : children(obj)) mark(*child) }
清除階段
// 標記清除偽代碼 1 sweep_phase(){ 2 sweeping = $heap_start // 從堆首地址開始 3 while(sweeping < $heap_end) // 遍歷每個標志位 4 if(sweeping.mark == TRUE) // 如果遍歷到已標記元素 5 sweeping.mark = FALSE // 將標記清除 6 else // 沒有遍歷到 7 sweeping.next = $free_list // 將其插在空閑鏈表頭部 8 $free_list = sweeping // 將空閑鏈表指針指向所有空閑鏈 9 sweeping += sweeping.size // 繼續(xù)進行查找 10 }
(3)觸發(fā)時機
垃圾收集器會按照固定的時間間隔或代碼執(zhí)行中預(yù)定的收集時間,周期性地執(zhí)行
參考文章
內(nèi)存管理
引用計數(shù)算法
GC-標記清除算法
深入理解作用域鏈(超贊)
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/99061.html
摘要:內(nèi)存回收此時,局部變量就沒有存在的必要了,因此可以釋放它們的內(nèi)存以供將來使用。局部變量會在它們離開執(zhí)行環(huán)境時自動被解除引用,如下面這個例子所示手工解除的引用由于局部變量在函數(shù)執(zhí)行完畢后就離開了其執(zhí)行環(huán)境,因此無需我們顯式地去為它解除引用。 JavaScript 具有自動垃圾收集機制(GC:Garbage Collecation),也就是說,執(zhí)行環(huán)境會負責管理代碼執(zhí)行過程中使用的內(nèi)存。而...
摘要:引入的同步算法傳統(tǒng)上,像以前的用到的引用計數(shù)內(nèi)存機制,無法處理循環(huán)引用的內(nèi)存泄漏。然而使用文章引用計數(shù)系統(tǒng)中的同步周期回收中的同步算法,解決了這個內(nèi)存泄漏問題,這種算法就是的垃圾回收機制。 引用賦值 $a = apple; $b = &$a; 上述代碼中,我將一個字符串賦值給變量a,然后將a的引用賦值給了變量b。顯然,這個時候的內(nèi)存指向應(yīng)該是這樣的: $a -> apple
摘要:垃圾回收內(nèi)存管理實踐先通過一個來看看在中進行垃圾回收的過程是怎樣的內(nèi)存泄漏識別在環(huán)境里提供了方法用來查看當前進程內(nèi)存使用情況,單位為字節(jié)中保存的進程占用的內(nèi)存部分,包括代碼本身棧堆。 showImg(https://segmentfault.com/img/remote/1460000019894672?w=640&h=426);作者 | 五月君Node.js 技術(shù)棧 | https:...
摘要:年輕代的目標就是盡可能快速的收集掉那些生命周期短的對象。年老代在年輕代中經(jīng)歷了次垃圾回收后仍然存活的對象,就會被放到年老代中。什么情況下觸發(fā)垃圾回收由于對象進行了分代處理,因此垃圾回收區(qū)域時間也不一樣。 [TOC] 與C/C++相比,java語言不需要程序員直接控制內(nèi)存回收,java程序的內(nèi)存分配和回收都是由JRE在后臺自動進行,JRE會負責回收那些不再使用的內(nèi)存,這種機制被稱為垃圾...
閱讀 1315·2021-11-15 11:37
閱讀 3504·2021-11-11 16:55
閱讀 1756·2021-08-25 09:39
閱讀 3220·2019-08-30 15:44
閱讀 1735·2019-08-29 12:52
閱讀 1408·2019-08-29 11:10
閱讀 3244·2019-08-26 11:32
閱讀 3226·2019-08-26 10:16