JavaScript的垃圾回收機(jī)制

垃圾回收

  • 程序是運(yùn)行在內(nèi)存里的,當(dāng)聲明一個變量、定義一個函數(shù)時都會占用內(nèi)存,當(dāng)變量或函數(shù)不再使用時,就把所分配的內(nèi)存空間釋放出來,就叫做垃圾回收,它是一種自動的內(nèi)存管理機(jī)制

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

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

  • 如果這個對象不再被引用,就會被回收
let obj1 = { A: 1 }; // A 的引用個數(shù)為 1 
let obj2 = obj1;     // A 的引用個數(shù)變?yōu)?2
obj1 = 0;            // A 的引用個數(shù)變?yōu)?1
obj2 = 0;            // A 的引用個數(shù)變?yōu)?0,此時對象 A 就可以被回收

標(biāo)記清除

  • 在變量進(jìn)入執(zhí)行環(huán)境時,會添加一個進(jìn)入標(biāo)記,當(dāng)變量離開時,會添加一個離開標(biāo)記,標(biāo)記清除是GC在運(yùn)行時會給所有變量加上標(biāo)記,然后去掉那些還在環(huán)境中或還被環(huán)境中變量引用的變量,清除剩下還被標(biāo)記的所有變量
  • 可能導(dǎo)致的問題是,清除后,內(nèi)容空間不連續(xù),產(chǎn)生了內(nèi)存碎片,可以用標(biāo)記整理來解決

常見的幾種情況

  • 引用計(jì)數(shù)中的循環(huán)引用
function func() {
    let obj1 = {};
    let obj2 = {};
    obj1.a = obj2; // obj1 引用 obj2
    obj2.a = obj1; // obj2 引用 obj1
}
//函數(shù)結(jié)束后,obj1,obj2的引用都不為0,因此不會被回收,這時需要手動將它們賦為null
obj1.a = null; obj2.a = null;
  • 在清空數(shù)組的時候,可以給array.length=0
  • DOM操作的時候,比如:liul的子元素,與父元素是引用關(guān)系,如果保存了li的引用,則ul會一直在內(nèi)存中
const button = document.getElementById('button');
document.body.removeChild(document.getElementById('button'));

雖然刪除了按鈕,但是button的引用還一直在內(nèi)存中,需要手動將button=null

總結(jié)

  • 可能導(dǎo)致內(nèi)存泄漏的一定是引用類型的變量,比如函數(shù)和其他自定義對象。值類型的變量是不存在內(nèi)存泄漏的,比如字符串、數(shù)字、布爾值等,因?yàn)橹殿愋褪强繌?fù)制來傳遞,而引用類型是靠指針來傳遞
  • 減少內(nèi)存垃圾的一個方法就是避免創(chuàng)建對象,創(chuàng)建對象的方式有new Object(); const obj = {};

內(nèi)存泄漏

  • 我們已經(jīng)無法再引用某個對象時,但垃圾回收器卻認(rèn)為這個對象還在被引用,因此在回收的時候不會釋放它
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容