1. 認(rèn)識(shí)內(nèi)存管理
不管以什么樣的方式來(lái)管理內(nèi)存串慰,內(nèi)存的管理都會(huì)有如下的生命周期
- 第一步:分配申請(qǐng)你需要的內(nèi)存(申請(qǐng))承疲;
- 第二步:使用分配的內(nèi)存(存放一些東西吆你,比如對(duì)象等)胧后;
- 第三步:不需要使用時(shí)肴盏,對(duì)其進(jìn)行釋放科盛;
不同的編程語(yǔ)言對(duì)于第一步和第三步會(huì)有不同的實(shí)現(xiàn):
- 手動(dòng)管理內(nèi)存:比如C、C++菜皂,包括早期的OC贞绵,都是需要手動(dòng)來(lái)管理內(nèi)存的申請(qǐng)和釋放的(malloc和free函數(shù));
- 自動(dòng)管理內(nèi)存:比如Java恍飘、JavaScript榨崩、Python、Swift章母、Dart等母蛛,它們有自動(dòng)幫助我們管理內(nèi)存;
2. JavaScript的內(nèi)存管理
JS對(duì)于原始數(shù)據(jù)類(lèi)型內(nèi)存的分配會(huì)在執(zhí)行時(shí)乳怎,直接在椝莼觯空間進(jìn)行分配;
JS對(duì)于復(fù)雜數(shù)據(jù)類(lèi)型內(nèi)存的分配會(huì)在堆內(nèi)存中
開(kāi)辟一塊空間,并且將這塊空間的指針?lè)祷刂?br>
變量引用焦辅;
3. JavaScript的垃圾回收
垃圾回收的英文是Garbage Collection博杖,簡(jiǎn)稱(chēng)GC;
常見(jiàn)的GC算法
- 引用計(jì)數(shù)(Reference counting)
- 當(dāng)一個(gè)對(duì)象有一個(gè)引用指向它時(shí)筷登,那么這個(gè)對(duì)象的引用就+1剃根;
- 當(dāng)一個(gè)對(duì)象的引用為0時(shí),這個(gè)對(duì)象就可以被銷(xiāo)毀掉前方;
這個(gè)算法有一個(gè)很大的弊端就是會(huì)產(chǎn)生循環(huán)引用
- 標(biāo)記清除(mark-Sweep)
標(biāo)記清除的核心思路是可達(dá)性(Reachability), 設(shè)置一個(gè)根對(duì)象(root object)狈醉,垃圾回收器會(huì)定期從這個(gè)根開(kāi)始,找所有從根開(kāi)始有引用到的對(duì)象惠险,對(duì)于哪些沒(méi)有引用到的對(duì)象苗傅,就認(rèn)為是不可用的對(duì)象;
早期js使用的就是這個(gè)算法
-
標(biāo)記整理(Mark-Compact) 和“標(biāo)記-清除”相似班巩;
- 不同的是渣慕,回收期間同時(shí)會(huì)將保留的存儲(chǔ)對(duì)象搬運(yùn)匯集到連續(xù)的內(nèi)存空間,從而整合空閑空間抱慌,避免內(nèi)存碎片化逊桦;
分代收集(Generational collection)—— 對(duì)象被分成兩組:“新的”和“舊的”。
增量收集(Incremental collection)
將垃圾收集工作分成幾部分來(lái)做抑进,然后將這幾部分會(huì)逐一進(jìn)行處理强经,這樣會(huì)有許多微小的延遲而不是一個(gè)大的延遲;閑時(shí)收集(Idle-time collection)
垃圾收集器只會(huì)在 CPU 空閑時(shí)嘗試運(yùn)行寺渗,以減少可能對(duì)代碼執(zhí)行的影響匿情。
4. V8引擎詳細(xì)的內(nèi)存圖
V8引擎使用了多種垃圾回收算法來(lái)管理內(nèi)存,其中主要使用分代收集算法信殊,包括新生代和老生代垃圾回收炬称。新生代垃圾回收使用復(fù)制算法和標(biāo)記-清除算法,而老生代垃圾回收則使用標(biāo)記-壓縮算法鸡号。