Photo by Mohammad Rahmani on Unsplash
低阶语言 (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
Donate KJ 贊助作者喝咖啡
如果這篇文章對你有幫助的話,可以透過下面支付方式贊助作者喝咖啡,如果有什麼建議或想說的話可以贊助並留言給我
If this article has been helpful to you, you can support the author by treating them to a coffee through the payment options below. If you have any suggestions or comments, feel free to sponsor and leave a message for me!
方式 Method | 贊助 Donate |
PayPal | https://paypal.me/kejyun |
綠界 ECPay | https://p.ecpay.com.tw/AC218F1 |
歐付寶 OPay | https://payment.opay.tw/Broadcaster/Donate/BD2BD896029F2155041C8C8FAED3A6F8 |