JavaScript是在創建變數(物件,字串等)時自動進行了分配記憶體,并且在不使用它們時“自動”釋放, 釋放的程序稱為垃圾回收,這個“自動”是混亂的根源,并讓JavaScript開發者錯誤的感覺他們可以不關心記憶體管理,
記憶體生命周期
不管什么程式語言,記憶體生命周期基本是一致的:

- 分配你所需要的記憶體
- 使用分配到的記憶體(讀、寫)
- 不需要時將其釋放\歸還
所有語言第二部分都是明確的,第一和第三部分在底層語言中是明確的,但在像JavaScript這些高級語言中,大部分都是隱含的,
js記憶體分配(值的初始化)
為了不讓程式員費心分配記憶體,JavaScript 在定義變數時就完成了記憶體分配,
var n = 123; // 給數值變數分配記憶體
var s = "azerty"; // 給字串分配記憶體
var o = {
a: 1,
b: null
}; // 給物件及其包含的值分配記憶體
// 給陣列及其包含的值分配記憶體(就像物件一樣)
var a = [1, null, "abra"];
function f(a){
return a + 2;
} // 給函式(可呼叫的物件)分配記憶體
// 函式運算式也能分配一個物件
someElement.addEventListener('click', function(){
someElement.style.backgroundColor = 'blue';
}, false)
使用值
使用值的程序實際上是對分配記憶體進行讀取與寫入的操作,讀取與寫入可能是寫入一個變數或者一個物件的屬性值,甚至傳遞函式的引數,
釋放記憶體
大多數記憶體管理的問題都在這個階段,在這里最艱難的任務是找到“哪些被分配的記憶體確實已經不再需要了”,它往往要求開發人員來確定在程式中哪一塊記憶體不再需要并且釋放它,高級語言解釋器嵌入了“垃圾回收器”,它的主要作業是跟蹤記憶體的分配和使用,以便當分配的記憶體不再使用時,自動釋放它,
垃圾回收
垃圾回識訓制分為兩種:
- 參考計數法: 這是最初級的垃圾收集演算法,此演算法把“物件是否不再需要”簡化定義為“物件有沒有其他物件參考到它”,如果沒有參考指向該物件(零參考),物件將被垃圾回識訓制回收,也就是說當前記憶體被占用一次,計數累加一次,移除占用就減1,減到0時,瀏覽器就回收它,
- 標記清除: 這個演算法把“物件是否不再需要”簡化定義為“物件是否可以獲得”,最常用的垃圾回識訓制就是標記清除,當變數進入執行環境時,被標記為'進入環境',當變數離開執行環境時,被標記為'離開環境',某一個時刻,垃圾回收器會過濾掉環境中的變數,以及被環境變數參考的變數,剩下的就是被視為準備回收的變數,
開發程序中遇到的記憶體泄漏情況:
記憶體泄露是指當一塊記憶體不再被應用程式使用的時候,由于某種原因,這塊記憶體沒有返還給作業系統或者記憶體池的現象,記憶體泄漏可能會導致應用程式卡頓或者崩潰,
在js中,常見的記憶體泄漏主要有5種
- 意外的全域變數
在非嚴格模式中,未定義的變數會被自動系結到全域物件上(window/global),比如:
function foo() {
bar= 'somthing...'
}
foo()
函式內部變數沒有定義,自動系結到全域物件,就相當于 window.bar = 'somthing...',全域變數不會被回收,函式執行完,變數就一直還在記憶體中沒有被釋放,
解決方法: 使用嚴格模式或者在變數使用完畢后設定為 null,以回收記憶體,
2. 閉包
function foo() {
let a = 1 // 外部訪問不到這個變數
function bar() {
return a // 這里將變數回傳出去
}
return bar() // return出來后就給window了所以一直存在記憶體中,因為一直在記憶體中,在IE里容易造成記憶體泄漏
}
foo()
原因:閉包可以維持函式內區域變數,使其得不到釋放,
解決:將事件處理函式定義在外部,解除閉包,或者在定義事件處理函式的外部函式中,洗掉對dom的參考,
3. 沒有清理的DOM元素參考
原因:dom元素移除,但對dom元素的參考沒有解除,會導致記憶體泄漏,
解決:手動洗掉,
4. 被遺忘的定時器或者回呼
原因:當不需要setInterval或者setTimeout時,定時器沒有被clear,定時器的回呼函式以及內部依賴的變數都不能被回收,造成記憶體泄漏,
解決:比如:vue使用了定時器,需要在beforeDestroy 中做對應銷毀處理,js也是一樣的
5. 子元素存在參考引起的記憶體泄漏
原因:div中的ul li 得到這個div,會間接參考某個得到的li,那么此時因為div間接參考li,即使li被清空,也還是在記憶體中,并且只要li不被洗掉,他的父元素都不會被洗掉,
解決:手動洗掉清空,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/373904.html
標籤:JavaScript
上一篇:BootStrap中模態框踩坑
