nodejs内存溢出 FATAL ERROR: CALL_AND_RETRY_0 Allocation failed – process out of memory

  spa项目总体迁移转为ssr后,改动以后部署一切还好,就是忽然有一天访问人数太多,node进程很容易就挂了自动重启。html

  最后通过压力测试,考虑到是堆内存溢出的问题,就报错误:FATAL ERROR: CALL_AND_RETRY_0 Allocation failed – process out of memorynode

一、复现结果:ios

  采用Jmeter作压力测试,1s50次,持续请求,观察node进程占用内存状况axios

  通过观察发现持续请求,node进程占用内存一直升高,最后达到1.4G左右,就不会再升,由于64位系统默认分配给node进程的上线就是1.4G,32位系统好像是0.7G。工具

  达到1.4G以后,持续1/2分钟左右,进程就挂,报错堆内存溢出:FATAL ERROR: CALL_AND_RETRY_0 Allocation failed – process out of memorypost

二、解决过程测试

  起初一直不知道缘由,因为以前一直有上篇报错:connect ECONNREFUSED 127.0.0.1:80错误解决,的问题,因此刚开始觉得是这个拒绝致使大量链接堆积致使,因此先解决了上述问题。ui

  可是解决了上述问题以后,依然没有用,仍是会报错。考虑到是页面的问题,因此换了一个纯静态页面请求,看是否由于页面代码的问题致使内存溢出,结果请求纯静态页面也是同样状况,这就不知道什么缘由了。url

  注意:其实这时候应该考虑到往上一层,去层层筛选,应该考虑进页面以前会有那些处理,好比nuxt里plugins,进页面以前就须要实例化这些东西。应该去考虑这些处理里面会不会致使内存泄漏。spa

  而我当时就是没有考虑到这一层,因此陷入了处理问题的盲区,只能考虑到使用工具去查询内存快照,而后再找那些地方出现内存泄漏点。

  后来考虑到上一层,因此就往plugins里去找,发现的确有内存泄漏的点,一样是由于总体迁移ssr,不是从0到1搭建重构,因此代码结构没有过多注意。我发现全局拦截器是引入的三方axios,那么每次拦截都会引入一次,致使大量的引用占用资源。问题找到,改掉以后,改成引用同一个三方资源,就没有问题了。而后把全部plugins里重复引用的资源都改成同一份引用,这样也能够减小一部分占用。

  改好以后,build,而后用Jmeter作压测,监控了100多万次样本检测,异常率很低0.1%,而且node进程不会上升了,占用内存稳定在200-250M之间,问题获得解决。

  记录一下主要是为了复盘一下解决问题的思路,由于解决问题的思路比解决问题的方法更重要:应该是从底层往上层,层层筛选,底层没问题,应该考虑紧邻它的上一层会不会有问题,这样就能快速定位,而我就是由于没有继续往上考虑一层,因此致使走了很多弯路。