Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Node.js(v8)垃圾收集器是如何工作的?_Javascript_Node.js_Memory Leaks_Garbage Collection - Fatal编程技术网

Javascript Node.js(v8)垃圾收集器是如何工作的?

Javascript Node.js(v8)垃圾收集器是如何工作的?,javascript,node.js,memory-leaks,garbage-collection,Javascript,Node.js,Memory Leaks,Garbage Collection,我已经用node.js应用程序做了一些测试,寻找我的代码应该做的内存泄漏。我运行的脚本在我看来应该会泄漏内存,但我对结果感到惊讶 redisClient.on('message', initRequest); function onSuccess(self, json){ console.dir(json); } function initRequest(channel, message){ var request = new RequestObject({ red

我已经用node.js应用程序做了一些测试,寻找我的代码应该做的内存泄漏。我运行的脚本在我看来应该会泄漏内存,但我对结果感到惊讶

redisClient.on('message', initRequest);

function onSuccess(self, json){
    console.dir(json);
}

function initRequest(channel, message){

  var request = new RequestObject({
      redisMessage: message
  });
  
  request.on('success', onSuccess);

}
redisClient每秒发出两个“消息”事件。这意味着
initRequest
函数经常被调用。每次
request
对象在内存中创建时,函数
onSuccess
都绑定到它的“success”事件

我假设(但这里我可能错了),只要有侦听器(
onSuccess
,在本例中)绑定到此对象,它就不能被垃圾收集。然后我想,内存使用量会增加,因为内存不会被释放

作为此潜在泄漏的解决方案,我想使用
.once
而不是
.on
,因为这将解除侦听器的绑定,并且对象可能会被垃圾收集

我已经使用pmap测试了这两种场景(比较了
上的
。和
上的
。一次
和另一个不值得在这里提及的场景),我没有发现很大的差异

总而言之,我有两个问题:

  • 这是在某些时间间隔内清理内存的正常GC行为,还是在内存达到某个阈值后,而不是在连续清理内存

  • 我是否正确地假设带有
    .on
    的示例代码应该会泄漏内存,这在内存消耗图上没有看到

  • 1:是:-)

    2:一般来说,当使用事件侦听器时,内存泄漏是因为阻止正在侦听的对象被垃圾收集,因为正在发出的对象保留了对它的引用

    因此,在您的代码中,
    onSuccess
    函数将被您的
    请求
    对象引用。但是,
    onSuccess
    只是一个函数,它被重用为所有请求对象的侦听器,因此不应导致内存累积


    旁注:我不知道
    redisClient
    RequestObject
    的内部结构,但在我看来,
    request
    函数完成后,也就是在调用它的任何侦听器之前,
    initRequest
    就可以进行垃圾收集了

    据我所知,请求对象应该只存在于initRequest函数中,因此应该在函数终止时标记为垃圾收集。

    一些想法。。。对于第一个问题,是的,这是正常的。垃圾收集以循环方式运行。当您不再有对某些内存的引用时,它可以被垃圾收集,但没有迹象表明何时会发生这种情况。至于第二个问题,我预计那里也会出现内存泄漏。古玩,看看为什么它在图表中不可见。为了清楚起见,你能用。一次显示代码吗?我假设你是在redisClient上做的,但现在只是猜测而已。此外,我确实看到1的使用率稍高一些。红线。。这就是“漏洞”吗?一个传奇故事就好了。由于onSuccess在所有initRequests之间共享,因此将使用极少的额外内存,因此,如果您的请求在达到几百万之前全部完成,我不会期望出现更高的峰值。您使用了哪个redis客户端模块?我搜索了
    RequestObject
    ,但没有得到任何有趣的结果。似乎我的担忧来自于对谁引用谁的错误假设。现在我知道事件emmiter引用的是侦听器,而不是相反的方式。