美文网首页
nodejs学习笔记——内存泄露问题研究

nodejs学习笔记——内存泄露问题研究

作者: AmazRan | 来源:发表于2019-08-04 17:05 被阅读0次

前言

起因是因为一个项目开发到后期文件数量越来越多,本地环境运行时有时候热重载失败断开服务。网络上绝大多数的解决方案是提高上限,假使通过其他手段定位内存泄漏问题,一般方案就是找那些不被使用又不会被释放的变量,处理了这些变量,问题一般就可以解决了。

vue-cli-service serve 命令会启动一个开发服务器 (基于 webpack-dev-server ) 并附带开箱即用的模块热重载 (Hot-Module-Replacement)。
vue-cli3.0并不支持直接添加--max-old-space-size去提高内存上限,需要安装依赖increase-memory-limit
--max-old-space-size,最大 old space 大小,执行 MarkSweep 回收,默认 1G,单位 MB


基础知识

Node.js 进程的内存管理,都是有 V8 自动处理的,包括内存分配和释放。
在 V8 内部,会为程序中的所有变量构建一个图,来表示变量间的关联关系,当变量从根节点无法触达时,就意味着这个变量不会再被使用了,就是可以回收的了
而这个回收是一个过程性的,从快速 GC (garbage collection) 到 最后的 Full GC,是需要一段时间的。
另外,Full GC 是有触发阈值的,所以可能会出现内存长期占用在一个高值,也可以算是一种内存泄漏;还有一种就是引用不释放,导致无法进入 GC 环节,并且一直产生新的占用,这一般会发生在 Javascript 层面。

所以,定位内存泄漏问题,一般方案就是找那些不被使用又不会被释放的变量,处理了这些变量,问题一般就可以解决了。如果是 Node.js 底层变量不释放,除了提交 issue 等待解决外,只能通过优化启动参数来解决。


流程

  1. 重现问题
    在平时写代码的时候,可以将一些重要环节的参数细节打印在 log 中,以便于我们排查问题。
    在 Node.js 的启动参数中,提供了暴露手动调用 GC 方法的参数,即 --expose-gc。我们用这个参数来启动应用后,就可以在代码中调用 global.gc() 手动触发垃圾回收操作。同时,使用 process.memoryUsage().heapUsed 获取进程运行时所占用的内存。如果 GC 之后,内存依然没有下降,就可以确定是内存泄露了。

  2. 生成内存快照
    taobaofed推荐,至少要生成三次内存快照,才能更好的定位问题。这三次中又一次要在问题出现前生成,之后可以在问题持续的过程中生成两次或更多。
    第一次是为了获取正常情况下的堆栈信息,而在问题出现后,堆栈信息一定会发生变化,有了第一次的信息,我们才好进行后面的比对,过滤一些无用的信息。而后两次的快照,用来比对某一对象的堆栈变化,来确定是否是有问题的对象。

  3. 定位问题
    对于内存快照,有四个视图,Summary、Comparison、Containment、Statistics。其中Comparison可以进行多个快照比对,使用较多。而路径视图可以清楚的分辨对象被哪个变量持有,哪些不存在引用却依然存在的。

  4. 解决问题
    一般在 Javascript 中存在引用而导致内存泄漏的情况,是比较好处理的,只需要在使用后及时的将引用释放掉即可。但如果属于底层机制的问题,如果等不了 bugfix,就只能先通过开篇讲的提高内存上限。


实际问题

taobaofed的同学很好的阐述了解决内存泄露问题的思路,那么回到我们遇到的实际问题:本地环境vue-cli3.0多次热更新后内存溢出。

查看源码,发现其也是简单调用了webpack hot-reload middleware。那么问题的本质就是,node服务因为webpack的一次次热重载且内存泄露导致了JavaScript heap out of memory。引起这个内存泄露的主要原因大概率不是因为webpack,而是存在于 Loaders/Plugins 或是与之相类似的。

这里我们可以借助工具:devtool,heapdump + chrome devTool 或者是 memwatch 去查看内存快照。

解决办法:找到引起问题的依赖或者是代码中会严重引起内存泄露的地方修改。若是依赖的问题,通过git issue和release log查看是否确实存在问题且已经修复再update。


心得体会

虽然起因和node服务内存泄露问题后所差距,但是问题原因和解决思路基本是一致的。相比解决问题,定位排查问题的根源更加困难。同时平时写代码也要多注意内存泄露的问题,养成良好的习惯。


参考

如何定位 Node.js 的内存泄漏
记一次 Node.js 应用内存暴涨分析
webpack Issue 6929

相关文章

  • nodejs学习笔记——内存泄露问题研究

    前言 起因是因为一个项目开发到后期文件数量越来越多,本地环境运行时有时候热重载失败断开服务。网络上绝大多数的解决方...

  • Java弱引用学习 WeakHashMap、ReferenceQ

    上一篇文章 Java内存泄露学习 ThreadLocal真的会内存泄露吗 提到ThreadLocal内存泄露的问题...

  • UIWebView内存泄露问题研究

    废话不多说,直接撸代码.一个简单的demo,创建UIWebView加载百度. UIWebView 利用instur...

  • nodejs 内存泄露 监测

    node-memory-leak-tutorial 按以下文章进行操作: https://github.com/f...

  • Android 内存优化总结&实践

    内存泄露 大部分的内存问题都是内存泄露导致的,Android里也有一些很常见的内存泄露问题这里简单罗列下: 详细见...

  • 关于华为inputMethodManager内存泄露

    一个关于内存泄露的问题,相信使用华为手机检测内存泄露的时候都会发现inputMethodManager内存泄露这个...

  • 内存泄露总结

    内存泄露会产生的问题: 1:内存泄露造成的第一个问题是异常,包括内存分配失败,OOM。 2:内存泄露造成的第二个问...

  • JS学习笔记_内存泄露

    常见的四中内存泄露:1:意外的全局变量JavaScript 处理未定义变量的方式比较宽松:未定义的变量会在全局对象...

  • 内存泄露问题

    在使用系统的CF或者CA开头的类,一定要注意,自己管理内存,要不容易内存泄露 值得一提的是,今天遇到了一个比较特别...

  • NodeJS中被忽略的内存

    原文链接:BlueSun | NodeJS中被忽略的内存 如朴灵说过,Node对内存泄露十分敏感,一旦线上应用有成...

网友评论

      本文标题:nodejs学习笔记——内存泄露问题研究

      本文链接:https://www.haomeiwen.com/subject/wwzddctx.html