浅谈Node的内存泄露问题


Posted in NodeJs onMay 06, 2022

1、node内存相关知识

无论是运行在浏览器端的js,还是运行在node中的js,关于内存管理的方案,都是通过垃圾回收机制来实现内存的分配和释放。当我们的代码编写有缺陷时,可能就无法通过gc来释放内存,这个时候,我们就造成了内存泄露。

  • Node.js进程的内存管理,都是由 V8 引擎自动处理的,包括内存的分配和释放。V8 自动处理内存的分配和释放,叫垃圾回收机制(gc)。

  • 垃圾回收机制,解决了大部分内存管理的问题,但是并不意味着内存泄露的问题就不存在。在一些特殊的场景下,会发生内存泄露。

  • 垃圾回收机制,是根据root对象(window/global)依次梳理对象的引用,如果能从root的引用链到达访问,V8就会将其标记为可到达对象,反之为不可到达对象。被标记为不可到达对象(即无引用的对象)后就会被 V8 回收。

2、哪些情况会造成内存泄露

第一、全局变量

全局变量会直接挂在root对象上,不会被清除掉。只要一个变量挂载到root对象上,自程序运行起,它就会一直占据着内存空间。

第二、函数闭包

闭包会引用父级函数的变量,如果闭包未释放,就会导致内存被持续占用,从而导致内存泄露。

在实际的业务场景中,引用的变量极有可能是挂载到从root可以追溯到的对象上,导致的内存泄露。

第三、事件监听

多次的重复的事件监听,可以导致内存泄露的问题。

3、内存泄露的监测

node的内存泄露监测,基本原理如下,

在node中,有专门进行内存监测的工具——heapdump。

heapdump,是一个npm包,使用比较简洁的语法,就能生成内存快照文件。

内存快照文件,是以heapsnapshot为扩展名的一种文件,该文件记录了关于内存使用的基本情况。

Chrome devTools作为一种工具,可以对内存快照文件,进行分析。

一段监测内存变化的代码如下:

const EventEmitter = require('events');
const heapdump = require('heapdump');
global.test = new EventEmitter();
heapdump.writeSnapshot('./' + Date.now() + '.heapsnapshot');
function run3() {
  const innerData = new Buffer(100);
  const outClosure3 = function () {
    void innerData;
  };
  test.on('error', () => {
    console.log('error');
  });
  outClosure3();
}
for(let i = 0; i < 100; i++) {
  run3();
}
// run3();
// gc();
heapdump.writeSnapshot('./' + Date.now() + '.heapsnapshot');

其中,heapdump.writeSnapshot方法,就是生成内存快照文件的方法。

我们使用node的方式,进行执行,就会生成两个heapsnapshot文件。

4、Chrome DevTools进行分析和对比

在Chrome DevTools => Memory => Profiles中,加载生成的两个heapsnapshot文件。

如下图所示,可以查看相应的内存占用情况:

浅谈Node的内存泄露问题

  • Summary:以构造函数名分类显示。
  • Comparison:比较多个快照之间的差异。
  • Containment:查看整个GC路径。
  • Statistics:以饼状图显示内存占用信息。

再看Statistics中关于内存占用的占比分析:

浅谈Node的内存泄露问题

再看Comparison中对比多个快照之间的差异。(可以很明显的看出增加的部分)

浅谈Node的内存泄露问题

5、内存分析的意义

从商业的角度来说,有时候我们无法通过代码,直观的看到内存泄露相关的信息,而这种内存分析的方式,给了我们解决问题的思路。

在现代化的业务开发中,内存监测是一种必要的工具,掌握了基本的原理,有助于我们分析和理解node性能分析的平台型工具。更有助于我们对node的理解。

到此这篇关于浅谈Node的内存泄露的文章就介绍到这了!


Tags in this post...

NodeJs 相关文章推荐
Nodejs中读取中文文件编码问题、发送邮件和定时任务实例
Jan 01 NodeJs
用NodeJS实现批量查询地理位置的经纬度接口
Aug 16 NodeJs
Nodejs进阶:核心模块net入门学习与实例讲解
Nov 21 NodeJs
Nodejs 发送Post请求功能(发短信验证码例子)
Feb 09 NodeJs
3分钟快速搭建nodejs本地服务器方法运行测试html/js
Apr 01 NodeJs
解析NodeJS异步I/O的实现
Apr 13 NodeJs
NodeJs的fs读写删除移动监听
Apr 28 NodeJs
Nodejs之http的表单提交
Jul 07 NodeJs
nodejs 如何手动实现服务器
Aug 20 NodeJs
NodeJS读取分析Nginx错误日志的方法
May 14 NodeJs
nodejs文件夹深层复制功能
Sep 03 NodeJs
nodejs如何在package.json中设置多条启动命令
Mar 16 NodeJs
分享node.js实现简单登录注册的具体代码
Apr 26 #NodeJs
分享五个Node.js开发的优秀实践 
Apr 07 #NodeJs
Node.js实现爬取网站图片的示例代码
NodeJs使用webpack打包项目的方法详解
Feb 28 #NodeJs
node快速搭建后台的实现步骤
nodejs利用readline提示输入内容实例代码
详解NodeJS模块化
You might like
PHP应用JSON技巧讲解
2013/02/03 PHP
下拉列表多级联动dropDownList示例代码
2013/06/27 PHP
Drupal7中常用的数据库操作实例
2014/03/02 PHP
函数中使用require_once问题深入探讨 优雅的配置文件定义方法推荐
2014/07/02 PHP
JSON 学习之完全手册 图文
2007/05/29 Javascript
jQuery提交多个表单的小技巧
2014/07/27 Javascript
使用node.js 制作网站前台后台
2014/11/13 Javascript
JS实现定时自动关闭DIV层提示框的方法
2015/05/11 Javascript
基于jquery实现ajax无刷新评论
2020/08/19 Javascript
jQuery实现ajax的叠加和停止(终止ajax请求)
2016/08/08 Javascript
bootstrap table动态加载数据示例代码
2017/03/25 Javascript
解决vue-router中的query动态传参问题
2018/03/20 Javascript
JavaScript面向对象程序设计创建对象的方法分析
2018/08/13 Javascript
vue下拉菜单组件(含搜索)的实现代码
2018/11/25 Javascript
vue中动态select的使用方法示例
2019/10/28 Javascript
js将URL网址转为16进制加密与解密函数
2020/03/04 Javascript
python在命令行下使用google翻译(带语音)
2014/01/16 Python
Python的Django框架中自定义模版标签的示例
2015/07/20 Python
Python全局变量用法实例分析
2016/07/19 Python
Python编程实现两个文件夹里文件的对比功能示例【包含内容的对比】
2017/06/20 Python
Python3实现将本地JSON大数据文件写入MySQL数据库的方法
2018/06/13 Python
Python使用sklearn库实现的各种分类算法简单应用小结
2019/07/04 Python
简单分析python的类变量、实例变量
2019/08/23 Python
python使用pip安装SciPy、SymPy、matplotlib教程
2019/11/20 Python
用CSS3实现无限循环的无缝滚动的实例代码
2017/07/04 HTML / CSS
HTML5无刷新改变当前url的代码
2017/03/15 HTML / CSS
canvas仿写贝塞尔曲线的示例代码
2017/12/29 HTML / CSS
英国现代家具和照明购物网站:Heal’s
2019/10/30 全球购物
商铺门前三包责任书
2014/07/25 职场文书
工商管理专业毕业生自我鉴定2014
2014/10/04 职场文书
英语演讲开场白
2015/05/29 职场文书
初中数学教学反思范文
2016/02/17 职场文书
PhpSpreadsheet中文文档 | Spreadsheet操作教程实例
2021/04/01 PHP
微信小程序用户授权最佳实践指南
2021/05/08 Javascript
nodejs利用readline提示输入内容实例代码
2021/07/15 NodeJs
万能密码的SQL注入漏洞其PHP环境搭建及防御手段
2021/09/04 SQL Server