【问题标题】:Memory leaks and closure problems in NodeJSNodeJS 中的内存泄漏和关闭问题
【发布时间】:2013-05-03 16:01:23
【问题描述】:

当我们开始测试我们的 NodeJS 项目时,我们注意到巨大的内存消耗。这是由我们整个项目的内存泄漏引起的。所以我们开始寻找所有可能产生内存泄漏的原因。在 stackoverflow 上有一些关于这个问题的答案,但是没有任何关于什么是内存泄漏和什么不是内存泄漏的严格文档。

我的问题:

  • 是否有关于 V8 GC 及其工作原理的文档(详细)?
  • 如何释放回调以便 GC 收集它们?
  • V8 GC 是否收集未使用但下方有函数闭包的变量?示例:

    var serviceChannel = require('./channel');
    var dataRegistration = require('../data/registration');
    
    function registerOnChannel(userID, channelID, callsuccess, callerror) {
    
        serviceChannel.findChannel(channelID, function (channel) {
            if (!channel) {
                callerror("Channel doesn' exists");
                return;
            }
            dataRegistration.registerOnChannel(userID, channelID, function (registration) {
                if (!registration) {
                    callerror("Registration doesn' exists");
                    return;
                }
                callsuccess("Registration successful");
            }, function (error) {
                callerror("Error on registration");
            })
        }, function (error) {
            callerror("Error on finding channel");
        })
    }
    

因此,只要 registerOnChanel 处于活动状态,serviceChannel 和 dataRegistration 就会保存在内存中。但是变量channel会被GC删除吗(没有被任何函数使用)?

【问题讨论】:

  • “因此,只要 registerOnChanel 处于活动状态,serviceChannel 和 dataRegistration 就会保存在内存中”。你是怎么得出这个结论的?
  • 在您发布的代码中没有关闭的证据,至少不会使 serviceChannel 或 dataRegistration 保持活动状态。
  • V8 如何知道我何时会进行回调(我可以不进行任何回调,一个或多个回调)并使用其中一个变量?如果 V8 在第一次回调后清空这个 vars,多个回调如何工作?

标签: node.js memory-leaks closures


【解决方案1】:

首先我想说你应该移动你的 API 以使用内置的 EventEmitter (http://nodejs.org/api/events.html)。

V8 GC 是否收集未使用但下方有函数闭包的变量?

如果您使用前一个函数作用域中的变量,那么该变量将不得不一直存在,直到包含函数作用域以及包含该变量的所有回调都超出作用域为止。

但是变量channel会被GC删除吗(它没有被任何函数使用)?

根据您发布的代码示例,是的,它将由 GC 收集。但是很有可能在没有注意到的情况下泄露了一个或两个参考。

【讨论】:

  • 我已经用这个例子的一些变体测试了 NodeJS,当没有人引用它们时,GC 总是删除对象和变量。我还注意到 GC 仅在需要时运行(惰性模式)。如果程序消耗了一些内存,则在发出新的内存分配请求之前,它不会被释放。 V8 GC 运行良好。
猜你喜欢
  • 2018-08-26
  • 1970-01-01
  • 1970-01-01
  • 2013-05-17
  • 1970-01-01
  • 2012-12-19
  • 2016-04-22
  • 1970-01-01
相关资源
最近更新 更多