背景

在阿里云上看到我运行了一段时间的程序,发现 memory 一项基本是在稳步提升,就知道有内存泄漏的情况出现。如下图

近三日从 35% 升到 40%,缓慢而坚定的提升。

代码

排查此问题需要分析其堆内存快照,当然我们不能直接使用线上机器调试。不幸的是测服机器在内网,和阿里云联不通,alinode 发挥不了作用。但所幸的是 V8 引擎提供了内部接口可以直接把堆中的JS对象导出来供开发者分析。我们采用heapdump这个模块,执行如下命令安装

$ npm install heapdump --save

"heapdump": "^0.3.15",

执行如下

const heapdump = require('heapdump');
heapdump.writeSnapshot(`./${Date.now()}.heapsnapshot`);

生成的文件如下

$ ll -lh

-rw-rw-r-- 1 souche souche  38M Nov 19 19:00 1574161221512.heapsnapshot

总之我在测服上定时每 2 小时打印堆栈快照。

总之,你可以使用 scp 命令把测服的代码导出到本地

# 传递单个文件

$ scp 【服务器用户名】@【服务器地址】:【服务器上存放文件的路径】【本地文件的路径】

# 例如

$ scp souche@172.11.xxx.xxx:/home/souche/app/egg-test/current/1574161221512.heapsnapshot /Users/dasouche/workspace/sc-node

# 传递文件夹

scp -r 【服务器用户名】@【服务器地址】:【服务器上存放文件的路径】【本地文件的路径】

分析步骤

打开 chrome-控制台-Memory-load

加载完后得到

简而言之,Shallow Size 就是对象自身被创建时所需要内存的大小,Retained Size 就是当把对象从支配树上拿掉,对象和它的下级节点一共能释放的内存大小。

其术语简介可参见:https://developers.google.com/web/tools/chrome-devtools/memory-problems/memory-101

分析过程

从线上机器导出两个堆文件,一个是10月30日打印的,一个是11月4日打印的,其内存上升了 100+ MB。

比对两个堆,把第二个堆文件的 Summary 切换成 Comparison,并按 Delta 倒叙排,发现增长最快的是 (concatenated string) 。其中有很多连接字符串,其中有大量的sql语句,并且有大量的schedule执行。

(constructor) 增长排第二,其中也见到不少 schedule,那我们可以确认就是 noticeJob.ts 这个定时器的问题。

本项目使用了 egg 作为框架,schedule 就是指定时触发的逻辑。联系代码我们发现在一个 5 秒触发一次的 schedule 里,里面不停的触发队列的 process 监听事件,猜测是 Queue.process 监听事件越绑越多的毛病,也导致里面的逻辑越触发越多。

这其实就是队列绑定监听事件的误用了。

// app/schedule/noticeJob.ts
'use strict'; import { Context } from 'egg';
import * as kue from 'kue'; module.exports = {
schedule: {
disable: false,
// 每五秒触发一次
cron: '*/5 * * * * *',
immediate: true,
type: 'worker',
}, async task(ctx: Context) {
const Queue = ctx.app.kue; Queue.process('noticeCalling', async function(job, done) {
const { uid, rid, subId } = job.data;
await ctx.service.message.noticedCalling(uid, rid);
// done();
});
},
};

我们在测服注释掉这段定时器后,每隔一小时打印一次(因为测服无法连阿里云),观察一天,内存没有上升趋势,这很好。

-rw-rw-r--  1 souche souche  38M Nov 24 11:24 1574565877609.heapsnapshot
-rw-rw-r-- 1 souche souche 37M Nov 24 12:24 1574569477611.heapsnapshot
-rw-rw-r-- 1 souche souche 38M Nov 24 13:24 1574573077611.heapsnapshot
-rw-rw-r-- 1 souche souche 38M Nov 24 14:24 1574576677613.heapsnapshot
-rw-rw-r-- 1 souche souche 38M Nov 24 15:24 1574580277614.heapsnapshot
-rw-rw-r-- 1 souche souche 38M Nov 24 16:24 1574583877614.heapsnapshot
-rw-rw-r-- 1 souche souche 38M Nov 24 17:24 1574587477616.heapsnapshot
-rw-rw-r-- 1 souche souche 38M Nov 24 18:24 1574591077616.heapsnapshot
-rw-rw-r-- 1 souche souche 38M Nov 24 19:24 1574594677616.heapsnapshot
-rw-rw-r-- 1 souche souche 38M Nov 24 20:24 1574598277618.heapsnapshot
-rw-rw-r-- 1 souche souche 37M Nov 24 21:24 1574601877620.heapsnapshot
-rw-rw-r-- 1 souche souche 38M Nov 24 22:24 1574605477621.heapsnapshot
-rw-rw-r-- 1 souche souche 38M Nov 24 23:24 1574609077622.heapsnapshot
-rw-rw-r-- 1 souche souche 38M Nov 25 00:24 1574612677622.heapsnapshot
-rw-rw-r-- 1 souche souche 38M Nov 25 01:24 1574616277622.heapsnapshot
-rw-rw-r-- 1 souche souche 38M Nov 25 02:24 1574619877623.heapsnapshot
-rw-rw-r-- 1 souche souche 38M Nov 25 03:24 1574623477624.heapsnapshot
-rw-rw-r-- 1 souche souche 38M Nov 25 04:24 1574627077626.heapsnapshot
-rw-rw-r-- 1 souche souche 38M Nov 25 05:24 1574630677627.heapsnapshot
-rw-rw-r-- 1 souche souche 38M Nov 25 06:24 1574634277627.heapsnapshot
-rw-rw-r-- 1 souche souche 38M Nov 25 07:24 1574637877628.heapsnapshot
-rw-rw-r-- 1 souche souche 38M Nov 25 08:24 1574641477629.heapsnapshot
-rw-rw-r-- 1 souche souche 38M Nov 25 09:24 1574645077630.heapsnapshot
-rw-rw-r-- 1 souche souche 39M Nov 25 10:24 1574648677630.heapsnapshot
-rw-rw-r-- 1 souche souche 39M Nov 25 11:24 1574652277632.heapsnapshot

解决方法

最后就在 app.ts 设置这个 process 的监听,移除 schedule 里的定时脚本

Node 内存泄漏排查案例的更多相关文章

  1. 轻松排查线上Node内存泄漏问题

    I. 三种比较典型的内存泄漏 一. 闭包引用导致的泄漏 这段代码已经在很多讲解内存泄漏的地方引用了,非常经典,所以拿出来作为第一个例子,以下是泄漏代码: 'use strict'; const exp ...

  2. Chrome JS内存泄漏排查方法(Chrome Profiles)

     原文网址:http://blog.csdn.net/kaitiren/article/details/19974269 JS内存泄漏排查方法(Chrome Profiles)   Google Ch ...

  3. windows 下面的内存泄漏排查.

    内存泄漏排查 一下本人只是简单的介绍一个实用, 如果读者很感兴趣, 可以查阅msdn自己去深入调查相关的API和原理. API 介绍 1. 马上打印泄漏信息:_CrtDumpMemoryLeaks() ...

  4. Java内存泄漏真实案例

    内存泄漏:当不再需要一个对象时,垃圾收集器会回收它:如果不需要的对象一直在产生而不被收回,就称作“内存泄漏”. 以下为本人在工作中遇到的内存泄漏的案例: 1.对于大量的请求,使用了Executors. ...

  5. 填坑总结:python内存泄漏排查小技巧

    摘要:最近服务遇到了内存泄漏问题,运维同学紧急呼叫解决,于是在解决问题之余也系统记录了下内存泄漏问题的常见解决思路. 本文分享自华为云社区<python内存泄漏排查小技巧>,作者:luti ...

  6. Netty堆外内存泄漏排查,这一篇全讲清楚了

    上篇文章介绍了Netty内存模型原理,由于Netty在使用不当会导致堆外内存泄漏,网上关于这方面的资料比较少,所以写下这篇文章,专门介绍排查Netty堆外内存相关的知识点,诊断工具,以及排查思路提供参 ...

  7. JS内存泄漏排查方法——Chrome Profiles

    一.概述 Google Chrome浏览器提供了非常强大的JS调试工具,Heap Profiling便是其中一个.Heap Profiling可以记录当前的堆内存(heap)快照,并生成对象的描述文件 ...

  8. 内存泄漏学习案例-1-ArrayList

    解决 内存泄漏 于是赶快登陆探测服务器,首先是 top free df 三连,结果还真发现了些异常. 我们的探测进程 CPU 占用率特别高,达到了 900%. 我们的 Java 进程,并不做大量 CP ...

  9. Spring Boot引起的“堆外内存泄漏”排查及经验总结

    小结: 检索词:C++内存分配器.jvm内存模型.gdb.内存泄露 https://tech.meituan.com/2019/01/03/spring-boot-native-memory-leak ...

随机推荐

  1. Chrome浏览器架构

    通用浏览器架构 它可以是一个具有许多不同线程的进程,也可以是具有几个通过IPC进行通信的多个线程的进程. 一个具有许多不同线程的进程 通过IPC进行通信的多个线程的进程 注意 这些不同的体系结构是实现 ...

  2. AJ学IOS(19)UI之QQ好友列表

    AJ分享,必须精品 先看效果图 哈哈,这次猫猫给来个动态的图片,这个看起来带劲 实现思路 首先建立模型 这里用到的是一个双层的模型. cell的实现 这里一看其实就知道是一个tableView,我们自 ...

  3. Apache SkyWalking

    Apache SkyWalking 什么是 SkyWalking SkyWalking 是观察性分析平台和应用性能管理系统. 提供分布式追踪.服务网格遥测分析.度量聚合和可视化一体化解决方案. 支持J ...

  4. 使用Docker快速搭建PHP开发环境

    最近有个同事找过来,希望我对在很早之前写的一个PHP网站上增加一些功能,当时开发使用xampp构建的本地开发环境,但是现在我的笔记本电脑已经更新,没有当时的开发环境.本着尽量不往电脑上装无用软件的原则 ...

  5. Windows下如何将一个程序设为开机自启

    1.放在  开始-启动(C:\Users\Qi\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup)2.修改注册表[HKEY_L ...

  6. 空间小姐姐生活照,我用python破解加密压缩包,无忧查看

    事情的经过是这样的: 又是奶茶,行吧行吧. 快点开工,争取李大伟回来之前搞定. 李大伟说是6位数字密码 那么我们可以利用python生成全部的六位数字密码 #生成从000000到99999的密码表f ...

  7. Cocos2d-x在win7下的android交叉编译环境

    cocos2d-x在win7下的Android交叉编译环境 2014年4月14日 cocos2d-x环境配置 前面把Visual Studio+Python开发环境配好了,但还没有讲如何在Androi ...

  8. C++基础 学习笔记五:重载之运算符重载

    C++基础 学习笔记五:重载之运算符重载 什么是运算符重载 用同一个运算符完成不同的功能即同一个运算符可以有不同的功能的方法叫做运算符重载.运算符重载是静态多态性的体现. 运算符重载的规则 重载公式 ...

  9. hashlib的md5计算

    hashlib的md5计算 hashlib概述 涉及加密服务:Cryptographic Services 其中 hashlib是涉及 安全散列 和 消息摘要 ,提供多个不同的加密算法借口,如SHA1 ...

  10. sqli lab 1-4

    less-1 爆库 id=1222' union select 1,group_concat(schema_name),database() from information_schema.schem ...