介紹
低層次的語言,如C,具有低級別的內存管理命令,如:malloc()和free(),需要開發者手工釋放內存。然而像javascript這樣的高級語言情況則不同,對象(objects, strings 等)創建的時候分配內存,當他們不在使用的時候內存會被自動回收,這個自動回收的過程被稱為垃圾回收。因為垃圾回收的存在,讓javascript等高級語言開發者產生了一個錯誤的認識,以為可以不用關心內存管理。
內存生命周期
不管什么樣的編程語言,內存的生命周期基本上是一致的。
分配你需要的內存
使用他進行讀寫操作
當內存不需要的時候,釋放資源
步驟1和步驟2對于所有語言都一樣,能明顯覺察到。至于步驟3,低級別語言需要開發者顯式執行。而對于像javascript這樣的高級語言,這部分操作是交給解析器完成的,所以你不會覺察到。
javascript中的分配操作
值的初始化
在為變量賦值的時候,javascript會完成內存的分配工作。
代碼如下:
var n = 123; // 為數字分配內存
var s = "azerty"; // 為字符串分配內存
var o = {
a: 1,
b: null
}; // 為包含屬性值的object對象分配內存
var a = [1, null, "abra"]; // 為包含值的數組分配內存
function f(a){
return a + 2;
} // 為函數分配內存(函數是可調用的對象)
// 函數表達式同樣也是對象,存在分配內存的情況
someElement.addEventListener('click', function(){
someElement.style.backgroundColor = 'blue';
}, false);
通過函數調用完成分配
一些函數當執行完畢之后,同樣存在對象分配的情況發生。
代碼如下:
var d = new Date();
var e = document.createElement('div'); // 分配一個 DOM 元素
一些方法會分配新值或者對象。
代碼如下:
var s = "azerty";
var s2 = s.substr(0, 3); // s2 是一個新的字符串
// 由于字符串是不變的,javascript會為[0, 3]范圍的內容創建一個新的字符串
var a = ["ouais ouais", "nan nan"];
var a2 = ["generation", "nan nan"];
var a3 = a.concat(a2); // 把 a 和 a2 結合在一起,產生一個新的數組
對值的使用
對值的使用,其實也就是對分配后的內存執行讀寫操作。這些操作包括:對變量或者對象的屬性進行讀寫操作,或者向函數傳遞參數。
當不再需要的時候,釋放內存
絕大多數內存管理的問題都發生在這個階段。最難做的事情是,如何判定分配的內存不再需要。這往往需要開發者做出判定,程序在什么時候不再需要內存,并釋放他所占資源。
高級語言的解析器中嵌入了一個叫做“垃圾收集器”的程序,他的工作是用來跟蹤內存的分配和使用,判定內存是否被需要,在不再需要的時候執行資源釋放操作。他只能獲得一個近似值,因為判斷一個內存是否被需要,這是個不確定的問題(不能通過一種算法解決)。
新聞熱點
疑難解答
圖片精選