如何防止 node.js 中的内存泄漏?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5733665/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 14:03:30  来源:igfitidea点击:

How to prevent memory leaks in node.js?

memory-leaksnode.js

提问by neebz

We know node.js provides us with great power but with great power comes great responsibility.

我们知道 node.js 为我们提供了强大的力量,但强大的力量伴随着巨大的责任。

As far as I know the V8 engine doesn't do any garbage collection. So what are the most common mistakes we should avoid to ensure that no memory is leaking from my node server.

据我所知,V8 引擎不做任何垃圾收集。那么我们应该避免哪些最常见的错误以确保我的节点服务器没有内存泄漏。

EDIT:Sorry for my ignorance, V8 does have a powerful garbage collector.

编辑:抱歉我的无知,V8 确实有一个强大的垃圾收集器。

回答by Raynos

As far as I know the V8 engine doesn't do any garbage collection.

据我所知,V8 引擎不做任何垃圾收集。

V8 has a powerful and intelligent garbage collector in build.

V8 在构建中有一个强大而智能的垃圾收集器。

Your main problem is not understanding how closures maintain a reference to scope and context of outer functions. This means there are various ways you can create circular references or otherwise create variables that just do notget cleaned up.

您的主要问题是不了解闭包如何维护对外部函数的范围和上下文的引用。这意味着您可以通过多种方式创建循环引用或以其他方式创建不会被清理的变量。

This is because your code is ambigiousand the compiler can not tell if it is safeto garbage collect it.

这是因为您的代码含糊不清,编译器无法判断垃圾收集它是否安全

A way to force the GC to pick up data is to null your variables.

强制 GC 获取数据的一种方法是将变量清零。

function(foo, cb) {
    var bigObject = new BigObject();
    doFoo(foo).on("change", function(e) {
         if (e.type === bigObject.type) {
              cb();
              // bigObject = null;
         }
    });
}

How does v8 know whether it is safe to garbage collect big object when it's in an event handler? It doesn't so you need to tell it it's no longer used by setting the variable to null.

v8 如何知道在事件处理程序中垃圾收集大对象是否安全?它不是,所以您需要通过将变量设置为 null 来告诉它不再使用它。

Various articles to read:

各种文章阅读:

回答by davetapley

I wanted to convince myself of the accepted answer, specifically:

我想说服自己接受已接受的答案,特别是:

not understanding how closures maintain a reference to scope and context of outer functions.

不理解闭包如何维护对外部函数的范围和上下文的引用。

So I wrote the following code to demonstrate how variables can fail to be cleaned up, which people may find of interest.

因此,我编写了以下代码来演示如何无法清除变量,人们可能会对此感兴趣。

If you have watch -n 0.2 'ps -o rss $(pgrep node)'running in another terminal you can watch the leak occurring. Note how commenting in either the buffer = nullorusing nextTickwill allow the process to complete:

如果您watch -n 0.2 'ps -o rss $(pgrep node)'在另一个终端中运行,您可以观察发生的泄漏。请注意在 thebuffer = nullusing 中的注释如何nextTick允许该过程完成:

(function () {
    "use strict";

    var fs = require('fs'),
        iterations = 0,

        work = function (callback) {
            var buffer = '',
                i;

            console.log('Work ' + iterations);

            for (i = 0; i < 50; i += 1) {
                buffer += fs.readFileSync('/usr/share/dict/words');
            }

            iterations += 1;
            if (iterations < 100) {
                // buffer = null;

                // process.nextTick(function () {
                    work(callback);
                // });
            } else {
                callback();
            }
        };

    work(function () {
        console.log('Done');
    });

}());

回答by kazelsama

active garbage collection with:

主动垃圾收集:

node --expose-gc test.js

and use with:

并与:

global.gc();

Happy Coding :)

快乐编码:)