Tag: 内存泄漏

节点stream导致大量内存占用或泄漏

我正在使用节点v0.12.7,并希望直接从数据库stream到客户端(用于文件下载)。 不过,使用stream时,我注意到了大量的内存占用(可能会发生内存泄漏)。 使用express,我创build了一个端点,只需将可读stream传递给响应,如下所示: app.post('/query/stream', function(req, res) { res.setHeader('Content-Type', 'application/octet-stream'); res.setHeader('Content-Disposition', 'attachment; filename="blah.txt"'); //…retrieve stream from somewhere… // stream is a readable stream in object mode stream .pipe(json_to_csv_transform_stream) // I've removed this and see the same behavior .pipe(res); }); 在生产中,可读stream从数据库中检索数据。 数据量非常大(1M +行)。 我用一个虚拟stream(见下面的代码)换出了这个可读stream,以简化debugging,并注意到相同的行为:我的内存使用量每次跳跃大约200M。 有时候,垃圾收集器会启动,内存会下降一点,但会线性上升,直到我的服务器内存不足。 我开始使用stream的原因是不必将大量的数据加载到内存中。 这是行为吗? 我还注意到,在stream式传输的时候,我的CPU使用率跳跃到了100%,块(这意味着其他请求无法处理)。 我用这个不正确? 虚拟可读stream代码 // Setup a custom readable var Readable […]

NodeJS内存消耗在无限循环中

我不知道这是一个与节点或V8的错误,但如果我运行下面的代码节点进程泄漏内存。 GC似乎从来没有踢过,在几秒钟内它消耗> 1GB的内存。 这是意想不到的行为。 我错过了什么吗? 代码如下: for(;;) { console.log(1+1); } 很显然,这是一个有点人为的情况,但我可以看到一个长期运行的过程永远不会释放内存的问题。 编辑:我试了v0.5.10(不稳定)和v0.4.12(稳定),不稳定的版本performance更好一点 – 稳定版本只是停止输出到控制台,但继续消耗内存,而稳定版本继续执行并消耗内存而不会暂停。

没有v8-profiler的Node.js内存泄漏

我试图追踪Node.js应用程序中的内存泄漏。 我已经尝试安装v8-profiler,但它不会编译…它看起来像一个死的项目 ,很多人试图使用,但得到同样的问题 – 很多从节点0.3.2很多,所以很长一段时间前。 有没有人知道一种方法来追捕Node.js应用程序中的内存泄漏,而不使用v8-profiler? 我有Eclipse运行与V8远程debugging工作,但无法find一种方法来查看内存使用情况/堆等

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

我已经做了一些testing与我的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对象在内存中创build时,函数onSuccess绑定到它的“成功”事件。 我假设(但在这里我可能是错的),只要有监听器(在这种情况下的onSuccess )绑定到这个对象,它不能被垃圾收集。 然后我想,内存使用量将会增长,因为内存不会被释放。 作为这个潜在的泄漏的解决scheme,我想使用.once而不是.on ,因为这将解除绑定的监听器和对象可以被垃圾收集。 我用pmap来testing两种情况(比较.on和.once以及另外一个不值得提的场景),而且我没有发现很大的差别。 总结我有两个问题: 这是正常的GC行为来清除内存在一定的时间间隔,或者它达到一些threashold而不是连续清理? 我正确地认为,与.on示例代码应该泄漏内存, .on我没有看到内存消耗图吗?

在JavaScript中封闭和callback内存泄漏

function(foo, cb) { var bigObject = new BigObject(); doFoo(foo, function(e) { if (e.type === bigObject.type) { cb(); // bigObject = null; } }); } 上面的例子显示了一个经典的,意外的(或者可能不是)内存泄漏的封闭。 V8垃圾收集器无法确定是否可以安全地删除bigObject因为它正在被多次调用的callback函数中使用。 一种解决方法是在callback函数中的作业结束时将bigObject设置为null 。 但是如果你使用了很多variables(假设有像bigObject这样的bigObject ,并且它们全部用于callback),那么清理这个变成了一个难题。 我的问题是这样的:有没有其他的方式来清理这些使用的variables? 编辑这里有另一个(现实世界)的例子:所以我从MongoDB中获取应用程序,并将其与其他应用程序进行比较。 mongodb的callback函数使用从该callback函数中定义的variables应用程序。 当我从mongodb得到结果后,我也将它作为callback函数返回(因为它是全部asynchronous的,我不能只写回车)。 所以实际上它可能发生,我一直传播callback到源… function compareApplications(application, condition, callback) { var model = database.getModel('Application'); model.find(condition, function (err, applicationFromMongo) { var result = (applicationFromMongo.applicationID == application.applicationID) […]

如何在Node.js / V8中debugging/分析非常长的GC暂停

我正在尝试在相对复杂的Node.js服务器应用程序中分析内存/ GC问题。 即使在非常适中的负荷下,它们在明显的时期也变得没有响应,而这些停顿随着时间的推移而变长。 使用–trace-gc参数运行可能会导致非常长的垃圾收集时间: [4805] 537 ms: Mark-sweep 17.6 (46.4) -> 10.3 (47.4) MB, 20 ms [allocation failure] [GC in old space requested]. [4805] 1338 ms: Mark-sweep 31.3 (58.4) -> 19.2 (57.2) MB, 40 ms [allocation failure] [promotion limit reached]. [4805] 2662 ms: Mark-sweep 58.0 (79.2) -> 43.9 (85.2) MB, 109 ms [Runtime::PerformGC] [promotion limit […]

为什么会在Node.js中导致资源泄漏?

如果您查看域的Node.js 文档的开头,它指出: 由于JavaScript在JavaScript中的工作原理,几乎没有任何方法可以安全地“捡起你离开的地方”,而不会泄漏引用或创build其他某种不明确的状态。 再次在代码示例中,它在第一部分中提到: 虽然我们已经阻止了突然重启的进程,但是我们正在疯狂地泄露资源 我想明白为什么是这样呢? 什么资源在泄漏? 他们build议您只使用域来捕获错误并安全地closures进程。 这是所有例外的问题,而不仅仅是在使用域时? 在Javascript中抛出和捕获exception是一个糟糕的做法吗? 我知道这是Python中的一种常见模式。 编辑 我可以理解,如果抛出一个exception,那么为什么在非垃圾收集语言中可能会有资源泄漏,因为如果引发exception,则可能运行的清除对象的任何代码都不会运行。 我可以想象的唯一原因是如果抛出一个exception存储引用的variables在引发exception的范围(也可能是调用堆栈中的东西),从而保持引用,然后exception对象保持周围,永远不会得到清理。 除非所引用的泄漏资源是引擎内部的资源。 UPDATE 我已经写了一个博客解释这个问题的答案现在好一点了。 一探究竟