一次 Node.js 内存溢出

作者:何方舟

现象

之前有发现,录播 node 有异常关闭的情况。

我们在1月3日有一次发布,而1月5日凌晨突然挂掉。

分析服务器内存曲线。

对应的详细内存

可以发现服务器内存达到最大值 8G 后就挂掉了,根据发布后内存有明显的上升趋势,且 GC 回收不明显,

初步判定是由于内存泄露导致。

内存分析

我们使用 heapdump 这个库来帮助我们查看内存变量的情况。临时创建一个创建快照的请求地址。

    server.route({
        method: ['GET', 'POST'],
        path: '/now.qq.com/p',
        handler: function (request, reply) {
            heapdump.writeSnapshot(function(err, filename) {  
              console.log('dump written to', filename);
            });
            reply('success')
        }
    });

heapdump 的 writeSnapshot 生成的内存快照文件,可以被 chrome 打开。

通过 ab 进行本地压测:

ab -X 127.0.0.1:8080 -n 1000 -c 100  'http://now.qq.com/h5/record.html?_wv=16778245&_bid=2380&vid=1055_42515315844044863100000000000000&nocache=1'

这些内存快照使用方法可以参考这篇文章:http://taobaofed.org/blog/2016/04/15/how-to-find-memory-leak/

我们对程序开始时和压测结合后的内存快照进行对比,发现存在大量的 string,array 变量未被回收,而其他对象都没有出现明显的堆积。是令人疑惑的是,分析相关的 string 后发现,这些变量并不存在泄露的可能。

考虑到 v8 gc 的方式:

  • 一种是对新生代区的 Scavenge算法,速度块,
  • 一种是对老生区的标记清除算法,由于单线程的原因会导致应用被阻塞。

这些变量依旧存在的原因只可能处于已移到老生区,暂时未被 gc。

分析未宕机前的内存图

内存有一个很健康的折线,可以看出并不存在泄露问题。

但是内存总量却在一个很高值,服务器内存上限是 8G,也就是说内存总量一直处于一个很危险的值。

但是为什么之前没有出现宕机问题呢?

结合 12.15,12.31,1.5 的pv视图。

31日由于活动的原因,录播 pv 涨了三倍,这时可以是因为内存溢出引起的宕机。

结论

因为内存上限设置不合理,引起的内存溢出问题。

之前压测时候只关注了是否存在内存泄露与cpu占用,而忽视了内存占用这个问题。

对于部署服务时,要根据机器的内存上限以及机器CPU核心数合理的设置单服务器的内存上限值。

原文链接:http://ivweb.io/topic/58b50896bd9e855ec2371729

相关推荐

ECMAScript 2015 (ES6) in Node.js(译)

nodejs中错误捕获的一些最佳实践

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Jaycekon

Java消息队列--JMS概述

1、什么是JMS  JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API...

3255
来自专栏java一日一条

2015年Java开发岗位面试题归类

3. 说说你知道的几个Java集合类:list、set、queue、map实现类咯。。。

581
来自专栏CSDN技术头条

Java 9的14个新特性总结

Java 9 包含了丰富的特性集。虽然Java 9没有新的语言概念,但是有开发者感兴趣的新的API和诊断命令。 我们将快速的,着重的浏览其中的几个新特性: ? ...

1995
来自专栏听雨堂

根据rpt文件打印报表

不用一个个地导入rpt文件,再去写固定的代码,而是每次动态的根据指定的名称去加载报表和打印   if(Session["PrintXml"]!=null)   ...

18110
来自专栏互扯程序

毕业季,跳槽季,不刷点面试题怎么能行?

现在是资源共享的时代,同样也是知识分享的时代,如果你觉得本文能学到知识,请把知识与别人分享。 前言 马上就是一年一度的毕业季 跳槽季,找工作三大要素,简...

3185
来自专栏Python私房菜

用装饰器封装Flask-WTF表单验证逻辑

对于有很多提交接口的项目来说,需要在每个路由下写相同的的逻辑,造成了大量的代码重复。在Flask-Login中,要把一个路由设置为登录后才能访问,只需要在路由上...

661
来自专栏Java帮帮-微信公众号-技术文章全总结

【大牛经验】Java9的新特性

Java 9 包含了丰富的特性集。虽然Java 9没有新的语言概念,但是有开发者感兴趣的新的API和诊断命令。

743
来自专栏决胜机器学习

RabbitMQ(三) ——发布订阅

RabbitMQ(三)——发布订阅 (原创内容,转载请注明来源,谢谢) 一、概述 RabbitMQ的发布订阅(Publish/Subscribe)...

2635
来自专栏Golang语言社区

无辜的goroutine

简介: 本文主要是针对一些对于goroutine的“指控”提出我自己的看法,特别是轩脉刃的一篇博客文章《论go语言中goroutine的使用》提出了gorout...

2865
来自专栏Golang语言社区

无辜的goroutine

简介: 本文主要是针对一些对于goroutine的“指控”提出我自己的看法,特别是轩脉刃的一篇博客文章《论go语言中goroutine的使用》提出了gorout...

34911

扫码关注云+社区