nodejs setTimeout内存泄漏?

v0.10.4

以下是导致内存使用量不断增加的简单循环:

function redx(){ setTimeout(function(){ redx() },1000); console.log('loop'); } redx(); 

我究竟做错了什么 ??

编辑

OK,只是尝试了引用范围内的超时对象的build议,似乎大约40秒后,垃圾收集踢在这里,从TOP的缩写日志:

3941根20 0 32944 7284 4084 S 4.587 3.406 0:01.32节点
3941根20 0 32944 7460 4084 S 2.948 3.489 0:01.59节点
3941根20 0 32944 7516 4084 S 2.948 3.515 0:01.68节点
3941根20 0 33968 8400 4112 S 2.948 3.928 0:02.15节点
3941根20 0 33968 8920 4112 S 3.275 4.171 0:02.98节点
3941根20 0 33968 8964 4112 S 2.948 4.192 0:03.07节点
3941根20 0 33968 9212 4112 S 2.953 4.308 0:03.16节点
3941根20 0 33968 9212 4112 S 2.953 4.308 0:03.25节点
3941根20 0 33968 9212 4112 S 3.276 4.308 0:03.35节点
3941根20 0 33968 9212 4112 S 2.950 4.308 0:03.44节点

不知道为什么,但显然,如果你在函数的作用域中引用超时对象,nodejs会做正确的垃圾收集。

 function redx(){ var t = setTimeout(function(){ redx() },50); console.log('hi'); } redx(); 

其实,我认为这可能只是V8垃圾收集器的工作方式。

在我的系统中,节点堆往往会增加到48 MB,然后稳定下来,所以我认为如果让程序长时间运行,内存消耗最终会稳定下来。

通过使用V8命令行选项之一启动节点,您可以获得关于何时/如何启动GC的信息:–trace_gc标志。

在您第一次尝试使用Redis时,您在每次调用时系统地连接/断开Redis。 这往往会产生垃圾。 你应该打开一次连接,并多次使用它。 尽pipe如此,即使我这样做,内存消耗趋于稳定。 下面是使用Redis的这个例子的内存消耗的演变:

 // something close to your initial function (when Redis was still in the picture) function redx(){ var client = redis.createClient(); client.get("tally", function(err, reply) { client.quit(); }); setTimeout(function(){ redx() }, 50 ); } 

使用Redis连接/断开内存消耗的演变

在这里,60MB以后的稳定似乎相当明显。