作者 | 五月君
Node.js 技术栈 | https://www.nodejs.red
慕课认证作者 | https://imooc.com/u/2667395
对于 Node.js 服务端研发的同学来说,关于垃圾回收、内存释放这块不需要向 C/C++ 的同学那样在创建一个对象之后还需要手动创建一个 delete/free 这样的一个操作进行 GC(垃圾回收), Node.js 与 Java 一样,由虚拟机进行内存自动管理。
但是这样并不表示就此可以高枕无忧了,在开发中可能由于疏忽或者程序错误导致的内存泄漏也是一个很严重的问题,所以做为一名合格的服务端研发工程师,还是有必要的去了解下虚拟机是怎样使用内存的,遇到问题才能从容应对。
快速导航
- Nodejs中的GC
- Nodejs垃圾回收内存管理实践
- 内存泄漏识别
- 内存泄漏例子
- 手动执行垃圾回收内存释放
- V8垃圾回收机制
- V8堆内存限制
- 新生代与老生代
- 新生代空间 & Scavenge 算法
- 老生代空间 & Mark-Sweep Mark-Compact 算法
- V8垃圾回收总结
- 内存泄漏
- 全局变量
- 闭包
- 慎将内存做为缓存
- 模块私有变量内存永驻
- 事件重复监听
- 其它注意事项
- 内存检测工具
Nodejs中的GC
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,这是来自 Node.js 官网的一段话,所以 V8 就是 Node.js 中使用的虚拟机,在之后讲解的 Node.js 中的 GC 其实就是在讲 V8 的 GC。
Node.js 与 V8 的关系也好比 Java 之于 JVM 的关系,另外 Node.js 之父 Ryan Dahl 在选择 V8 做为 Node.js 的虚拟机时 V8 的性能在当时已经领先了其它所有的 JavaScript 虚拟机,至今仍然是性能最好的,因此我们在做 Node.js 优化时,只要版本升级性能也会伴随着被提升。
Nodejs垃圾回收内存管理实践
先通过一个 Demo 来看看在 Node.js 中进行垃圾回收的过程是怎样的?
内存泄漏识别
在 Node.js 环境里提供了 process.memoryUsage 方法用来查看当前进程内存使用情况,单位为字节
- rss(resident set size):RAM 中保存的进程占用的内存部分,包括代码本身、栈、堆。
- heapTotal:堆中总共申请到的内存量。
- heapUsed:堆中目前用到的内存量,判断内存泄漏我们主要以这个字段为准。
- external: V8 引擎内部的 C++ 对象占用的内存。
/**
* 单位为字节格式为 MB 输出
*/
const format = function (bytes) {
return (bytes / 1024 / 1024).toFixed(2) + ' MB';
};
/**
* 封装 print 方法输出内存占用信息
*/
const print = function() {
const memoryUsage = process.memoryUsage();
console.log(JSON.stringify({
rss: format(memoryUsage.rss),
heapTotal: format(memoryUsage.heapTotal),
heapUsed: format(memoryUsage.heapUsed),
external: format(memoryUsage.external),
}));
}
内存泄漏例子
堆用来存放对象引用类型,例如字符串、对象。在以下代码中创建一个 Fruit 存放于堆中。
// example.js
function Quantity(num) {
if (num) {
return new Array(num * 1024 * 1024);
}
return num;
}
function Fruit(name, quantity) {
this.name = name
this.quantity = new Quantity(quantity