浅谈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的url截取模块url-extract的使用实例
Nov 18 NodeJs
nodejs教程之异步I/O
Nov 21 NodeJs
用nodeJS搭建本地文件服务器的几种方法小结
Mar 16 NodeJs
nodejs爬虫遇到的乱码问题汇总
Apr 07 NodeJs
浅析 NodeJs 的几种文件路径
Jun 07 NodeJs
Nodejs+express+ejs简单使用实例代码
Sep 18 NodeJs
nodejs操作mongodb的增删改查功能实例
Nov 09 NodeJs
Nodejs连接mysql并实现增、删、改、查操作的方法详解
Jan 04 NodeJs
nodejs初始化init的示例代码
Oct 10 NodeJs
NodeJS模块与ES6模块系统语法及注意点详解
Jan 04 NodeJs
NodeJs 模仿SIP话机注册的方法
Jun 21 NodeJs
Nodejs 识别图片类型的方法
Aug 15 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+SQL 注入攻击的技术实现以及预防办法
2011/01/27 PHP
php匹配字符中链接地址的方法
2014/12/22 PHP
php绘制一个扇形的方法
2015/01/24 PHP
详解PHP数组赋值方法
2015/11/07 PHP
php获取是星期几的的一些常用姿势
2019/12/15 PHP
use jscript List Installed Software
2007/06/11 Javascript
Jquery 学习笔记(一)
2009/10/13 Javascript
基于JQuery的数字改变的动画效果--可用来做计数器
2010/08/11 Javascript
热点新闻滚动特效的js代码
2013/08/17 Javascript
Java/JS获取flash高宽的具体方法
2013/12/27 Javascript
浅谈Javascript中深复制
2014/12/01 Javascript
JavaScript实现的一个日期格式化函数分享
2014/12/06 Javascript
jquery+html5时钟特效代码分享(可设置闹钟并且语音提醒)
2020/03/30 Javascript
jquery左右全屏大尺寸多图滑动效果代码分享
2015/08/28 Javascript
Bootstrap入门书籍之(三)栅格系统
2016/02/17 Javascript
input type=file 选择图片并且实现预览效果的实例
2017/10/26 Javascript
nodejs实现OAuth2.0授权服务认证
2017/12/27 NodeJs
JS使用canvas中的measureText方法测量字体宽度示例
2019/02/02 Javascript
Vue中CSS动画原理的实现
2019/02/13 Javascript
Vue图片浏览组件v-viewer用法分析【支持旋转、缩放、翻转等操作】
2019/11/04 Javascript
Vue状态模式实现窗口停靠功能(灵动、自由, 管理后台Admin界面)
2020/03/06 Javascript
vue.js实现照片放大功能
2020/06/23 Javascript
[02:44]DOTA2英雄基础教程 魅惑魔女
2014/01/07 DOTA
详解Python中的文本处理
2015/04/11 Python
Python运算符重载详解及实例代码
2017/03/07 Python
python中matplotlib实现最小二乘法拟合的过程详解
2017/07/11 Python
Python 模拟登陆的两种实现方法
2017/08/10 Python
python分布式计算dispy的使用详解
2019/12/22 Python
详解Canvas 实现炫丽的粒子运动效果(粒子生成文字)
2018/02/01 HTML / CSS
给校长的建议书100字
2014/05/16 职场文书
高中教师先进事迹材料
2014/08/22 职场文书
今日说法观后感
2015/06/08 职场文书
python 中的@运算符使用
2021/05/26 Python
用Python爬取英雄联盟的皮肤详细示例
2021/12/06 Python
高通2023 年将发布高性能PC处理器
2022/04/29 数码科技
JS前端使用canvas实现扩展物体类和事件派发
2022/08/05 Javascript