Node内存泄漏

收集所有存在内存泄漏的所有case。哪怕一个字节也不放过。

Case1:无限制增长的数组

varleakArray=[];exports.leak=function(){leakArray.push("leak"+Math.random());};

这个大概是最常见的内存泄漏案例。只要变量leakArray不被回收,内存就有可能无限上涨,且不被回收。

解决方案

确认你push元素的数组对象是可以随着作用域执行结束回收。



Case2:无限制设置属性和值

这个情形在缓存对象中经常出现:

_.memoize=function(func,hasher){varmemo={};hasher||(hasher=_.identity);returnfunction(){varkey=hasher.apply(this,arguments);return_.has(memo,key)?memo[key]:(memo[key]=func.apply(this,arguments));};};

memoize方法主要是用来解决昂贵CPU耗用的js运算的。它十分有用。但是在后端使用的时候要十分小心。因为memo对象是不会回收的,每次的参数不同都会在这个对象上添加属性和值。

这个案例中,memo对象被当作了缓存来使用,一直无法得到回收。

解决方案

关于如何规避这种无限制缓存的问题,请移步到我另开的帖子中看解决方案:http://cnodejs.org/topic/4fafc843e7656c60680306f9



Case3:任何模块内的私有变量和方法均是永驻内存的

(function(exports,require,module,__filename,__dirname){varcircle=require('./circle.js');console.log('The area of a circle of radius 4 is '+circle.area(4));exports.get=function(){returncircle();};});

任意编写的模块文件中,均会在头和尾部上添加字符串,以形成闭包,然后在require的过程中被调用一次,并且将exports对象存储在内存中,直到进程退出才会回收。

这个案例中,只是内存不会回收,但一般不会造成内存泄漏。需要注意的是私有变量不要通过exports上的方法为其添加内存占用。

第一个案例其实就是由于这个原因造成的。



第四个案例来自于http://cnodejs.org/topic/4fcd020be5e72c25180032e5

//OOM测试for(vari=0;i<100000000;i++){varuser={};user.name='outmem';user.pass='123456';user.email='outmem[@outmem](/user/outmem).com';}

这段代码最主要的原因在于循环太大,直接内存分配到超过v8内存限制数量。由于JavaScript事件循环的执行机制,这段代码没有机会进入下一个事件循环。用setInterval和setTimeout可以进入下一个循环。但是不推荐用setInterval和setTimeout。

在Node下有一个特殊的方法,process.nextTick();

for(vari=0;i<100000000;i++){process.nextTick(function(){varuser={};user.name='outmem';user.pass='123456';user.email='outmem[@outmem](/user/outmem).com';});}

不过这样的效率可能不够好。因为每次都没有效利用好一次循环。

一个建议是,一次事件循环,不要超过10ms。太长时间的事件循环,不仅会存在oom的风险,还会阻塞后续IO的启动。



http://alinode.aliyun.com/blog/37

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • topics: 1.The Node.js philosophy 2.The reactor pattern 3....
    宫若石阅读 1,132评论 0 1
  • https://nodejs.org/api/documentation.html 工具模块 Assert 测试 ...
    KeKeMars阅读 6,420评论 0 6
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,780评论 18 399
  • Node.js是目前非常火热的技术,但是它的诞生经历却很奇特。 众所周知,在Netscape设计出JavaScri...
    w_zhuan阅读 3,642评论 2 41
  • 我很难悄悄 悄悄的如一滴雨落下 没有闪电 或者没有雷声 甚至天空没有什么变化 就悄悄的落下 我很难 我很难做到
    朱朱老老阅读 139评论 0 1