zoukankan      html  css  js  c++  java
  • 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次请求,结果发现内存占用比之前少了很多,基本上不会出现内存溢出的问题了。

  • 相关阅读:
    Java时间日期格式转换
    数据库性能优化
    java 词法分析器
    hdu 1018 Big Number
    hdu 1233 还是畅通工程
    hdu 2583 permutation 动态规划
    Sublime Text 3 安装 Package Control 结果返回 275309,找不到 Install Package
    Sublime Text 常用快捷键(Mac环境)
    sublime设置 reindent 快捷键
    scrollWidth、clientWidth 和 offsetWidth
  • 原文地址:https://www.cnblogs.com/ldld/p/10670638.html
Copyright © 2011-2022 走看看