express 内存溢出问题分析定位
一、现象
1. 如下报错
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
1: node::Abort() [/usr/local/bin/node]
2: node::OnFatalError(char const*, char const*) [/usr/local/bin/node]
3: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [/usr/local/bin/node]
4: v8::internal::Factory::NewFixedArray(int, v8::internal::PretenureFlag) [/usr/local/bin/node]
5: v8::internal::OrderedHashTable<v8::internal::OrderedHashMap, 2>::Rehash(v8::internal::Handle<v8::internal::OrderedHashMap>, int) [/usr/local/bin/node]
6: v8::internal::Runtime_MapGrow(int, v8::internal::Object**, v8::internal::Isolate*) [/usr/local/bin/node]
7: 0x2ecd2d1042fd
8: 0x2ecd2d1b251e
2.在linux服务器上输入top命令,发现该进程memery占用居高不下。
二、内存泄漏介绍
由上述问题可以确认,该node服务内存泄露. Node.js 进程的内存管理,都是有 V8 自动处理的,包括内存分配和释放。那么 V8 什么时候会将内存释放呢?
在 V8 内部,会为程序中的所有变量构建一个图,来表示变量间的关联关系,当变量从根节点无法触达时,就意味着这个变量不会再被使用了,就是可以回收的了。 而这个回收是一个过程性的,从快速 GC 到 最后的 Full GC,是需要一段时间的。 另外,Full GC 是有触发阈值的,所以可能会出现内存长期占用在一个高值,也可以算是一种内存泄漏,可以从《一次 Node.js 应用内存暴涨分析》中找到例子。还有一种就是引用不释放,导致无法进入 GC 环节,并且一直产生新的占用,这一般会发生在 Javascript 层面。
所以,定位内存泄漏问题,一般方案就是找那些不被使用又不会被释放的变量,处理了这些变量,问题一般就可以解决了。如果是 Node.js 底层变量不释放,除了提交 issue 等待解决外,只能通过优化启动参数来解决。
三、问题定位
1、看代码,代码里面是否存在闭包或者变量声明或者引用不当的地方。
2、是否引用node-canvas 或者echart等大型消耗cpu内存资源等依赖包
3、借助工具来分析,比如heapdump + chrome浏览器 memery分析工具
四、问题修复以heapdump为例,分析并修复内存泄漏的问题(基于express项目)。
1、项目根目录下安装heapdump
// node version > v0.8
npm install heapdump
// Or, if you are running node.js v0.6 or v0.8:
npm install heapdump@0.1.0
2、入口文件引入这个heapdump
// express中,在app.js中加入
const heapdump = require('heapdump');
3、重启该express服务,top(mac 上通过 top -pid xxx 查看) 命令查看linux占用情况:,
并发起少数几次请求后,输入如下命令,生成heap快照文件,记作name1
kill -USR2 <pid>
4、模拟批量服务请求
由于我这个是可以提供给web调用的接口,因此用一个抓包工具charles(或者其他模拟请求工具都行),重复发1000次请求,在用top命令查看该进程memery占用情况。发现问题可以重现了。同时输入如下命令:
// in UNIX platforms
kill -USR2 <pid>
// 执行上述命令,会生成一下heap快照的文件,记作name2

5、拷贝name1、name2文件到本地,并在chrome浏览器中打开分析;
6 、经过上述对比分析,可以得知代码存在的问题,然后作出相关优化。
比如,我这里是用到了node-canvas 和 Echart,最后发现这两个对象引用后一直没有内内存回收,导致内存溢出。代码层面做如下优化:
stage.destroy();
chart.dispose();
chart = null;
stage = null;
然后,启动服务,模拟1000次请求,结果发现内存占用比之前少了很多,基本上不会出现内存溢出的问题了。
express 内存溢出问题分析定位的更多相关文章
- jvm内存溢出问题的定位方法
jvm内存溢出问题的定位方法 今天给大家带来JVM体验之内存溢出问题的定位方法. 废话不多说直接开始: 一.Java堆溢出 测试代码如下: import java.util.*; public cla ...
- 记一次内存溢出的分析经历——thrift带给我的痛orz
说在前面的话 朋友,你经历过部署好的服务突然内存溢出吗? 你经历过没有看过Java虚拟机,来解决内存溢出的痛苦吗? 你经历过一个BUG,百思不得其解,头发一根一根脱落的烦恼吗? 我知道,你有过! 但是 ...
- 记一次内存溢出的分析经历——使用thrift
背景: 有一个项目做一个系统,分客户端和服务端,客户端用c++写的,用来收集信息然后传给服务端(客户端的数量还是比较多的,正常的有几千个), 服务端用Java写的(带管理页面),属于RPC模式,中间的 ...
- android 内存溢出问题分析
最近的项目中,内存一直再增长,但是不知道是什么问题,导致内存溢出,在网上看到了这么一篇关于内存分析与管理的文章,解决了部分问题,感觉这篇文 章还不错,就转帖到我的blog上了,希望对大家有所帮助. ...
- Java常见内存溢出异常分析(OutOfMemoryError)
原文转载自:http://my.oschina.net/sunchp/blog/369412 1.背景知识 1).JVM体系结构 2).JVM运行时数据区 JVM内存结构的相关可以参考: http:/ ...
- JVM:Java常见内存溢出异常分析
转载自:http://www.importnew.com/14604.html Java虚拟机规范规定JVM的内存分为了好几块,比如堆,栈,程序计数器,方法区等,而Hotspot jvm的实现中,将堆 ...
- tomcat 内存溢出原因分析及解决
一.错误提示:java.lang.OutOfMemoryError: Java heap space [原因分析] tomcat默认可以使用内存为128MB,在较大型的应用项目中不足以满足运行要求,在 ...
- (一)深入java虚拟机之内存溢出与分析
一.内存溢出程序 public class Test { public static void main(String[] args) { List<User> userList=new ...
- 本地模拟内存溢出并分析Dump文件
java Dump文件分析 前言 dump文件是java虚拟机内存在某一时间点的快照文件,一般是.hprof文件,下面自己模拟一下本地内存溢出,生成dump文件,然后通过mat工具分析的过程. 配置虚 ...
随机推荐
- shopex-百度爬虫抓取过于频繁导致php-cgi占用CPU过高的解决办法
步骤 1.开启slowlog:php-fpm里修改配置 观察slowlog里的超时文件,然后修改相应超时文件 2.1修改完后,仍然无效,查看access.log,发现大量如下的请求 220.181.1 ...
- 为Owin项目增加WebApi
上一篇文章我们新建了一个Owin项目. 本节,我们来为其增加WebApi功能 项目右键>添加>新搭建基架的项目 选择Web API 2控制器 为默认控制器命名 点击添加后项目结构如下: 将 ...
- soapui的简单使用
工具下载地址:https://www.soapui.org/downloads/soapui.html 名词解释 https://www.cnblogs.com/fcfblog/p/5830205.h ...
- dm_analysis
# -*- coding: utf-8-*- # import sys import os import io import json reload(sys) sys.setdefaultencodi ...
- JavaScript 对象属性底层原理
对象属性类型 1. 数据属性 [[Configurable]]:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性,特性默认值为true [[Enum ...
- LeetCode——17. Letter Combinations of a Phone Number
一.题目链接: https://leetcode.com/problems/letter-combinations-of-a-phone-number/ 二.题目大意: 给定一段数字字符串,其中每个数 ...
- 在Ubuntu下编译Qt错误及处理办法
平台:Ubuntu16.04 64bit 虚拟机:VirtualBOX 编译软件:Qt 32bit (在64位环境下编译32bit的程序会出现很多错误,从编译器的安装以及整个库的编译) 问题一:er ...
- jenkins 构建完毕后接着构建另外一个构建的方法
- mysql常规巡检
mysql常规巡检 目录 一.巡检脚本 二.下载巡检脚本 三.脚本执行说明 1.inspection.conf 使用说明 2.inspection_mysql.sh 使用说明 3.mysqltun ...
- 通过setup.py安装项目dependencies
一.使用方法 安装命令 $ pip install -e <option> setup.py 二.具体介绍 pip intall -e 举例一个setup.py $ pip int ...