記憶體管理 Memory Management
Node.js 記憶體管理 Memory Management
低階語言 (e.g. C, C++)
需要開發者自己決定,當程式執行到某個地方時,是否有已被分配的記憶體不再需要。並手動將其釋放。
高階的語言 (e.g. JavaScript)
有一個叫作 垃圾回收器(garbage collector)
的系統,他的工作是追蹤記憶體分配的使用情況,以便自動釋放一些不再使用的記憶體空間。
但這個垃圾回收器只是「儘量」做到自動釋放記憶體空間,因為判斷記憶體空間是否要繼續使用,這件事是「不可判定(undecidable)」的(不能用演算法來解決)。
Garbage collection 垃圾回收機制流程
瀏覽器偵測到某個物件不在被使用時,會執行垃圾回收(garbage collection)
的機制,以此釋放記憶體空間。
- 定期從根物件 (root,在瀏覽器中是 window,node 則是 global) 開始往下探詢每一個子節點
- 並清除沒有被探詢到、或是沒有被探詢物件參考的物件,也就是所謂「無法到達的物件 (unreachable objects)」
如果 root -> F
的參考消失,導致 F 變成「無法到達的物件」
,那麼 F 與其子節點們就會被自動回收。
Stack & Heap
- 比較簡單類型的 Primitive Type 會被放在 stack 裡
- 比較複雜類型的 Reference Type 則會把
資料存在 heap 中
,再把資料在heap 的記憶體位址
記錄到 stack 裡
可以看到 Object 類型的數據實際上是存在 Heap 裡,Stack 中存的只是物件在 Heap 中的記憶體位置而已
變數 four = three
這段 code 實際上是把 Three 指向的物件在 Heap 中的記憶體位置
指派給 Four 變數,所以它們實際上指向的是同一個物件
Stack & Heap Garbage collection 回收機制
如果是物件的話,Stack 中存的是 Heap 空間的 address
所以就算 Stack 被回收,存在 Heap 空間的數據依然存在,這時就需要靠 GC 來判斷 Heap 空間中哪些資料是用不到且需要被回收的
刪除變數釋放記憶體
使用 delete 刪除物件屬性
const Employee = {
name: 'Kay',
age: 17
};
// Kay
console.log(Employee.name);
// 刪除物件屬性值
delete Employee.name;
// undefined
console.log(Employee.name);
// { age: 17 }
console.log(Employee);
將變數設為 null
var myVar = "Hello";
// Hello
console.log(myVar);
myVar = null;
// null
console.log(myVar);
clearInterval() 清除無用的 Timer
function setCallback() {
// 拆解變數將 counter 獨立
let counter = 0;
// 在 setCallback 回傳 return 資料後會被移除
const hugeString = new Array(100000).join('x');
return function cb() {
// 只有 counter 是 callback 的 scope 變數
counter++;
console.log(counter);
}
}
// 儲存 Interval Timer ID
const timerId = setInterval(setCallback(), 1000); // saving the interval ID
// 清除 Timer
clearInterval(timerId);
移除元素前先移除 Event Listener
避免元素還有其他變數在使用,所以移除前,相關的綁定使用的變數要先移除
- 移除 Event Listener
- 移除元素
var element = document.getElementById('button');
function onClick(event) {
element.innerHtml = 'text';
}
element.addEventListener('click', onClick);
// 移除 Event Listener
element.removeEventListener('click', onClick);
// 移除元素
element.parentNode.removeChild(element);
參考資料
- 記憶體管理 - JavaScript | MDN
- 内存管理 - JavaScript | MDN
- [web] 記憶體問題 memory leak | PJCHENder 未整理筆記
- 從你的 Node.js 專案裡找出 Memory leak,及早發現、及早治療! | 方格子
- Load testing for engineering teams | Grafana k6
- Trash talk: the Orinoco garbage collector · V8
- 4 Types of Memory Leaks in JavaScript and How to Get Rid Of Them
- 網站常見 Memory Leak: 循環參照、事件循環監聽、存取全域變數 | 前端三分鐘 | 一起用三分鐘分享技術與知識
- JavaScript 記憶體洩漏(Memory Leak)問題 - G. T. Wang
- 身為 JS 開發者,你應該要知道的記憶體管理機制. 如果你是寫 C/C++… | by 莫力全 Kyle Mo | Starbugs Weekly 星巴哥技術專欄 | Medium
- Memory Leaks in JavaScript and how to avoid them. | by Eduard Hayrapetyan | Preezma Software Development Company | Medium