Co oznaczają wartości zwracane przez metodę node.js process.memoryUsage ()?


134

Z oficjalnej dokumentacji ( źródło ):

process.memoryUsage ()

Zwraca obiekt opisujący użycie pamięci przez proces Node mierzony w bajtach.

var util = require('util');

console.log(util.inspect(process.memoryUsage()));

To wygeneruje:

{ rss: 4935680, heapTotal: 1826816, heapUsed: 650472 }

heapTotal i heapUsed odnoszą się do użycia pamięci w wersji 8.

Co dokładnie oznacza rss , heapTotal i heapUsed ?

To może wydawać się banalne pytanie, ale szukałem i do tej pory nie mogłem znaleźć jasnej odpowiedzi.

Odpowiedzi:


159

Aby odpowiedzieć na to pytanie, należy najpierw zrozumieć schemat pamięci V8.

Działający program jest zawsze reprezentowany przez pewną przestrzeń przydzieloną w pamięci. Ta przestrzeń nosi nazwę Resident Set . V8 wykorzystuje schemat podobny do Java Virtual Machine i dzieli pamięć na segmenty:

  • Kod : aktualnie wykonywany kod
  • Stos : zawiera wszystkie typy wartości (prymitywy, takie jak liczby całkowite lub logiczne) ze wskaźnikami odwołującymi się do obiektów na stercie i wskaźnikami definiującymi przepływ sterowania w programie
  • Sterta : segment pamięci przeznaczony do przechowywania typów referencyjnych, takich jak obiekty, łańcuchy i zamknięcia. wprowadź opis obrazu tutaj

Teraz łatwo odpowiedzieć na pytanie:

  • rss : Rozmiar zestawu rezydenta
  • heapTotal : całkowity rozmiar sterty
  • heapUsed : Sterta faktycznie używana

Ref : http://apmblog.dynatrace.com/2015/11/04/understanding-garbage-collection-and-hunting-memory-leaks-in-node-js/


43
Obraz może być wart 1000 słów.
bmacnaughton

9
@bmacnaughton Ten jest wart 1013 słów :)
alex

2
[rss, heapTotal, heapUsed] => rozmiar w megabajtach? kilobajty? czy możesz to dodać do swojej odpowiedzi? czy wszystkie są tymi samymi jednostkami?
Alexander Mills,

Jak zarządzany jest heapTotal przez node? W mojej aplikacji widzę, że heapTotal stale rośnie (niezależnie od GC), mimo że heapUsed pozostaje ograniczony. Nie widziałem żadnego wyjaśnienia, w jaki sposób heapTotal jest zarządzany przez węzeł ... Wydaje mi się, że jest to po prostu zarezerwowana sterta dla przyszłych alokacji, ale czy którykolwiek z nich został kiedykolwiek wydany (jeśli nie jest używany)? Co sprawi, że pozostanie na haju?
logidelic

1
jest nowa właściwość „external” w process.memoryUsage (), każdy o tym wie

39

RSS to rezydentny rozmiar zestawu , czyli część pamięci procesu przechowywana w pamięci RAM (w przeciwieństwie do przestrzeni wymiany lub części przechowywanej w systemie plików).

Sterty jest częścią pamięci, z którego nowo przydzielone obiekty będą pochodzić z (myśleć mallocw C, lub neww JavaScript).

Możesz przeczytać więcej o stercie w Wikipedii .


4
Nie sądzę, że to całkowita pamięć. Na moim komputerze całkowita pamięć wynosi 8 GB, ale kiedy uruchamiam prosty proces węzłowy, RSS pokazuje około 13 MB, więc myślę, że naprawdę pokazuje, ile pamięci jest przechowywane w pamięci RAM przez ten proces.
Stefan

1
@Stefan racja, natknąłem się wtedy na jakiś błąd, ale teraz wydaje mi się, że RSS jest dla mnie niezawodny.
Mahn

4
Jaka jest różnica między heapTotali heapUsed?
tiblu

3
@tiblu heapTotalto całkowita przydzielona przestrzeń sterty przez bazowy silnik V8 dla dynamicznych alokacji. heapUsedjest pamięcią używaną w tej całkowitej przestrzeni. Oba są zarządzane przez V8 i mogą rosnąć / zmniejszać się w razie potrzeby.
elyas-bhy

4
Obraz, który wizualizuje różne przestrzenie pamięci: apmblog.dynatrace.com/wp-content/uploads/2015/11/DK_2.png
elyas-bhy

9

Dokumentacja Node.js opisuje to w następujący sposób:

heapTotal i heapUsed odnoszą się do użycia pamięci V8. External odnosi się do wykorzystania pamięci przez obiekty C ++ powiązane z obiektami JavaScript zarządzanymi przez V8. rss, Resident Set Size , to ilość miejsca zajmowanego w głównym urządzeniu pamięci (to jest podzbiór całkowitej przydzielonej pamięci) dla procesu, który obejmuje stertę, segment kodu i stos.

Wszystkie wymienione wartości są wyrażone w bajtach. Tak więc, jeśli chcesz je tylko wydrukować, prawdopodobnie chcesz przeskalować je do MB:

const used = process.memoryUsage();
for (let key in used) {
  console.log(`Memory: ${key} ${Math.round(used[key] / 1024 / 1024 * 100) / 100} MB`);
}

To da ci wyjście takie jak:

Memory: rss 522.06 MB
Memory: heapTotal 447.3 MB
Memory: heapUsed 291.71 MB
Memory: external 0.13 MB

1

Zróbmy to na przykładzie

Poniższy przykład pokaże, jak wzrost użycia pamięci faktycznie zwiększy rssiheapTotal

const numeral = require('numeral');
let m = new Map();
for (let i = 0; i < 100000; i++) {
    m.set(i, i);
    if (i % 10000 === 0) { 
        const { rss, heapTotal } = process.memoryUsage();
        console.log( 'rss', numeral(rss).format('0.0 ib'), heapTotal, numeral(heapTotal).format('0.0 ib') )
    } 
}

Running Powyższe da ci coś takiego:

rss 22.3 MiB 4734976 4.5 MiB
rss 24.2 MiB 6483968 6.2 MiB
rss 27.6 MiB 9580544 9.1 MiB
rss 27.6 MiB 9580544 9.1 MiB
rss 29.3 MiB 11419648 10.9 MiB
rss 29.3 MiB 11419648 10.9 MiB
rss 29.3 MiB 11419648 10.9 MiB
rss 32.8 MiB 15093760 14.4 MiB
rss 32.9 MiB 15093760 14.4 MiB
rss 32.9 MiB 15093760 14.4 MiB

To wyraźnie pokazuje, jak użycie zmiennej i ciągłe zwiększanie wymaganej przez nią przestrzeni zwiększa heapTotal i odpowiednio Resident Set Size ( rss)

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.