Node.js 中的 内存控制

简介: Node.js 中的 内存控制

内存控制

V8 的垃圾回收机制与内存限制

  • V8 的内存限制

    • 只能使用部分内存,导致 Node 无法直接操作大内存对象
    • 在 V8 中,所有的 JS 对象都是通过堆来进行分配的
    • 限制堆大小原因是 V8 的垃圾回收机制,垃圾回收中引起 JS 线程暂停执行的时间,应用的性能和响应能力会直线下降
  • V8 的垃圾回收机制

高效使用内存

  • 作用域

    • 全局变量需要进程退出才能释放,可以通过 delete 来删除引用关系,或重新赋值让旧的对象脱离引用关系
    • 在 V8 中通过 delete 删除对象的数学有可能导致干扰 V8 的优化,所以通过赋值解除引用更好
  • 闭包

    • 一旦有变量引用中间函数,这个中间函数将不会被释放,同时也会使原始的作用域不会得到释放,作用域中产生的内存占用也不会得到释放

内存指标

  • 查看内存使用情况

    • 查看进程内存占用 process.memoryUsage()
    • 查看系统内存占用
    os.totalmem()
    os.freemem()
  • 堆外内存

    • 堆外内存可以突破内存限制的问题
  • Node 的内存构成主要由通过 V8 进行分配的部分和 Node 自行分配的部分

    • 受 V8 的垃圾回收限制的主要是 V8 的堆内存

内存泄露

  • 造成内存泄露的原因

    • 缓存
    • 队列消费不及时
    • 作用域未释放
  • 慎将内存当做缓存

    • 需要限定缓存对象的大小,加上完善的过期策略以防止内存无限制增长
    • 尽量使用进程外的缓存,减少常驻内存的对象的数量,让垃圾回收更高效,进程之间可以共享缓存(Redis,Memcached)
  • 关注队列状态

    • 消费速度低于生产速度,将会形成堆积,需加强预警监控

内存泄漏排查

  • v8-profiler 对 V8 堆内存抓取快照和对 CPU 进行分析
  • node-heapdump 对 V8 堆内存抓取快照,用于事后分析
  • node-memwatch

大内存应用

Node 提供 stream 模块用于处理大文件
var reader = fs.createReadStream('in.txt');
var writer = fs.createWriteStream('out.txt');

reader.on('data', function (chunk) {
  writer.write(chunk);
});
reader.on('end', function () {
  writer.end();
});

// 简写
var reader1 = fs.createReadStream('in.txt');
var writer1 = fs.createWriteStream('out.txt');
reader1.pipe(writer1);
相关文章
|
29天前
|
存储 Kubernetes 容器
【CKA模拟题】查找集群中使用内存最高的node节点
【CKA模拟题】查找集群中使用内存最高的node节点
16 1
|
8月前
|
存储 JavaScript 前端开发
|
1天前
|
存储 缓存 JavaScript
【Web 前端】JS哪些操作会造成内存泄露?
【4月更文挑战第22天】【Web 前端】JS哪些操作会造成内存泄露?
|
4月前
|
JavaScript
WebAssembly01-- 在js中分配内存
WebAssembly01-- 在js中分配内存
25 0
WebAssembly01-- 在js中分配内存
|
4月前
|
Java
一招轻松解决node内存溢出问题
一招轻松解决node内存溢出问题
|
5月前
|
JavaScript Java
JS内存泄漏是什么 什么情况下会出现内存泄漏 内存泄漏怎么解决
JS内存泄漏是什么 什么情况下会出现内存泄漏 内存泄漏怎么解决
17 0
|
10月前
|
存储 JavaScript 前端开发
JS进阶(三) 闭包,作用域链,垃圾回收,内存泄露
闭包,作用域链,垃圾回收,内存泄露 1、函数创建 创建函数 1、开辟一个堆内存(16进制的内存地址) 2、声明当前函数的作用域(再哪个上下文创建的,它的作用域就是谁) 3、把函数体内的代码当作字符串存储在堆内存当中(所以不执行没有意义) 4、把函数的堆内存地址类似对象一样放到栈中供对象调用 执行函数 1、会形成一个全新的私有上下文(目的是供函数中的代码执行),然后进栈执行 2、在私有上下文中有一个存放私有变量的变量对象 AO(xx) 3、在代码执行之前要做的事情 - 初始化它的作用域链<自己的上下文,函数的作用域> - 初始化this (箭头函数没有this) - 初始化Arguments实参
65 0
|
7月前
|
JavaScript 前端开发 程序员
|
7月前
|
JavaScript API
使用 Node.js Stream API 减少服务器端内存消耗的一个具体例子
使用 Node.js Stream API 减少服务器端内存消耗的一个具体例子
60 0
|
8月前
如何检测node中是否存在内存泄露的隐患
如何检测node中是否存在内存泄露的隐患
29 0