Jak zapobiec wyciekom pamięci w węźle.js?

Znamy węzeł.js daje nam wielką moc, ale z wielką mocą przychodzi wielka odpowiedzialność.

Z tego co wiem silnik V8 nie robi żadnych śmieci. Więc jakie są najczęstsze błędy, których powinniśmy unikać, aby upewnić się, że żadna pamięć nie wycieka z mojego serwera węzłów.

EDIT: Przepraszam za moją ignorancję, V8 ma potężnego garbage collector.

Author: mikl, 2011-04-20

3 answers

Z tego co wiem silnik V8 Nie zbieraj śmieci.

V8 ma potężny i inteligentny garbage collector w kompilacji.

Twoim głównym problemem jest nie zrozumienie, w jaki sposób zamknięcia zachowują odniesienie do zakresu i kontekstu funkcji zewnętrznych. Oznacza to, że istnieją różne sposoby tworzenia odniesień okrągłych lub w inny sposób tworzenia zmiennych, które po prostu Nie zostają oczyszczone.

To dlatego, że Twój kod jest dwuznaczny i kompilator nie może stwierdzić, czy jest bezpieczne aby śmieci go zbierać.

Sposobem na zmuszenie GC do pobierania danych jest anulowanie zmiennych.

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

Skąd v8 wie, czy jest bezpiecznie zbierać duże obiekty, gdy jest w obsłudze zdarzeń? Nie jest, więc musisz powiedzieć, że nie jest już używany przez ustawienie zmiennej NA null.

Różne artykuły do przeczytania:

 64
Author: Raynos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-20 16:48:37

Chciałem się przekonać do zaakceptowanej odpowiedzi, a konkretnie:

Nie rozumiejąc, w jaki sposób zamknięcia zachowują odniesienie do zakresu i kontekstu funkcji zewnętrznych.

Więc napisałem następujący kod, aby zademonstrować, jak zmienne mogą nie być oczyszczone, co ludzie mogą znaleźć interesujące.

Jeśli masz watch -n 0.2 'ps -o rss $(pgrep node)' uruchomiony w innym terminalu, możesz obserwować wyciek. Zauważ jak komentować w buffer = null lub użycie nextTick pozwoli na proces do zakończenia:

(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');
    });

}());
 21
Author: dukedave,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-31 00:14:46

Aktywne zbieranie śmieci z:

node --expose-gc test.js

I używać z:

global.gc();

Happy Coding:)

 7
Author: kazelsama,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-17 23:04:11