Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Erläuterung der Speicherverwaltungsschritte von Nodejs

Detaillierte Erläuterung der Speicherverwaltungsschritte von Nodejs

php中世界最好的语言
php中世界最好的语言Original
2018-05-22 09:21:101475Durchsuche

Dieses Mal werde ich Ihnen die Schritte der Nodejs-Speicherverwaltung ausführlich erläutern. Was sind die Vorsichtsmaßnahmen für die Nodejs-Speicherverwaltung? Hier sind praktische Fälle.

s werden in verschiedenen Host-Umgebungen ausgeführt, und auch die entsprechenden Anforderungen an die Speicherverwaltung sind unterschiedlich. Wenn die Host-Umgebung ein Browser ist, ist die Laufzeit der Webseite kurz und sie wird nur auf dem Computer des Benutzers ausgeführt (entsprechend). zu Verteilt), selbst wenn der Speicher zu stark genutzt wird oder ein gewisser Speicherverlust auftritt, hat dies keine großen Auswirkungen auf den Endbenutzer. Wenn die Host-Umgebung zum Programmieren des Servers (Knoten) verwendet wird, ist die Situation ganz anders. Der Code selbst läuft auf einigen festen Maschinen (zentralisiert) und die Laufzeit ist lang. Es kommt zu einer Speichererweiterung, selbst wenn ein Speicherverlust auftritt, wird die serverseitige Antwortzeit länger oder es kommt sogar zum Absturz des Dienstes.

Nodejs basiert auf V8, sodass die in Node verwendeten JavaScript-Objekte (Puffer nicht) grundsätzlich über V8 zugewiesen und verwaltet werden. V8 begrenzt die Speichergröße, die es belegt (für ein 64-Bit-Betriebssystem beträgt die maximale Heap-Speichergröße, die von einem einzelnen Knotenprozess verwendet werden kann, etwa 1,5 GB). Selbst wenn der Server über einen großen Speicher verfügt, kann Node aufgrund dieser Einschränkung von V8 die Ressourcen des Servers nicht vollständig nutzen. Warum gibt es beim V8 dennoch solche Einschränkungen? Der Grund für diese Einschränkung hängt tatsächlich mit dem Garbage-Collection-Mechanismus zusammen. Am Beispiel des 1,5-GB-Garbage-Collection-Heapspeichers benötigt V8 mehr als 50 ms für eine kleine Garbage Collection und sogar mehr als 1 s für eine vollständige Garbage Collection Sie müssen den Müll kennen. Während des Recyclingprozesses muss sich der JavaScript-Thread in einem vorübergehenden Zustand befinden, der große Auswirkungen auf die Leistung des Back-End-Dienstes hat hat Grenzen für den Heap-Speicher. Dennoch bietet V8 immer noch eine Möglichkeit, die Heap-Speichergröße anzupassen (--max-old-pace-size), wobei old-space die alte Generation und new-space die neue Generation darstellt.

node --max-old-space-size=xxx index.js //单位为MB
// 之前还可以通过-max-new-space-size来定义新生代堆大小,现在已经不可以了

Wenn der Server aufgrund von Speicherlecks häufig neu startet, wird empfohlen, zuerst die Heap-Speichergröße zu erhöhen, um Zeit für die Fehlersuche zu gewinnen. Schließlich ist eine langsame Servicereaktion für Benutzer besser als die Rückgabe einer Fehlerseite Akzeptiere es ein wenig.

Warum brauchen wir alte und neue Generation?

Die alte Generation und die neue Generation sind tatsächlich unterschiedliche Generationen im Generations-Garbage-Collection-Mechanismus, da kein Garbage-Collection-Algorithmus für alle Szenarien geeignet ist und unterschiedliche Objektlebenszyklen tatsächlich unterschiedliche erfordern Die beste Recyclingstrategie kann die besten Ergebnisse erzielen, daher verwendet V8 einen Generations-Garbage-Collection-Mechanismus. Die Objekte werden entsprechend ihrer Überlebenszeit in verschiedene Generationen unterteilt, und dann ist der Speicher verschiedener Generationen (neue Generation, alte Generation) besser geeignet .

Objekte der neuen Generation haben eine kürzere Überlebenszeit, während Objekte der alten Generation eine längere Überlebenszeit haben oder sogar im Speicher verbleiben. Der darauf basierende Speicher der neuen Generation ist im Allgemeinen viel kleiner als der Speicher der alten Generation. Der maximale Speicher der neuen Generation in V8 beträgt 32 MB (64-Bit-System als Beispiel) und der maximale Speicher der alten Generation beträgt 1400 MB. Die tatsächlich von V8 verwendete Heap-Speichergröße ist die Summe des von der neuen Generation + der alten Generation verwendeten Speichers (1432 MB), aber der Maximalwert von V8 ist tatsächlich 32 MB (1464 MB) größer als die verwendete Speicherpaargröße

Neugeborenes Wie führt man die Müllabfuhr durch?

Die neue Generation verwendet einen Garbage-Collection-Algorithmus namens Scavenge. In der spezifischen Implementierung von Scavenge wird hauptsächlich der Cheney-Algorithmus verwendet. Der Cheney-Algorithmus teilt den Heap der neuen Generation in zwei Teile, von denen einer verwendet wird (vom Halbraum) und der andere im Leerlauf ist (zum Halbraum). Beim Erstellen eines Objekts wird es jetzt im From-Bereich zugewiesen. Wenn eine Speicherbereinigung erforderlich ist, werden die überlebenden Objekte im From-Bereich überprüft und dann in den To-Bereich kopiert Durch den Austausch von „From“ und „To“ besteht der gesamte Speicherbereinigungsprozess darin, die verbleibenden Objekte zwischen den beiden Seispaces zu kopieren. Bei Szenen mit kurzem Lebenszyklus machen die überlebenden Objekte einen relativ kleinen Anteil des gesamten Objekts aus, sodass Scavenge das Kopieren der überlebenden Objekte verwendet, Scavenge jedoch nur die Hälfte des Heap-Speicherplatzes nutzen kann ein typischer Raumtausch. Die Verkörperung der Zeit.

当一个对象经过多次垃圾回收依然存活的话,就会被认为是生命周期较长的对象,一方面新生代堆比较小,另一方面重复复制生命周期长的对象也很没有效率,所以对于生命周期长的对象会被移到老生代中去。新生代对象移动到老生代有两个对象:1.对象是否是生命周期较长的对象(已经经历过垃圾回收)2.To空间使用占比是否超过了25%。限制25%的原因是由于垃圾回收完成后To会变成From,如果不做限制的话可能会出现From很快被用光的情况,出现频繁的垃圾回收,也会影响效率。

老生代如何做垃圾回收?

老生代由于存活对象占较大比重,不适合对存活对象进行操作,使用Scavenge算法就不太合适了,因此老生代采用了Mark-Sweep和Mark-Compact相结合的方式。

Mark-Sweep分为标记和清除两个阶段,在标记阶段遍历堆中所有对象,标记活着的对象,然后在清除阶段未被标记的对象将会被清除掉。Mark-Sweep解决了内存释放的问题但是由于没有像Scavenge那样复制对象的操作导致内存碎片化不连续。而Mark-Compact就是用来解决内存碎片化问题的。Mark-Compact会将存活的对象往一端移动,移动完成后直接清理掉边界外的内存,这样就有大段的连续可用内存了,但是由于涉及到对象的移动,因此Mark-Compact的速度要比Mark-Sweep慢了。V8主要使用Mark-Sweep,只有当空间不足以对新生代中今生过来的对象进行分配时才使用Mark-Compact。

垃圾回收过程中会导致应用程序暂停执行,由于新生代本身空间较小,且要复制的存活对象占比也少,因此即便执行全量垃圾回收也影响不大,但是老生代空间很大,存活对象也多,执行一次全量垃圾回收对于应用程序暂停会是一个比较长的时间,因此V8将老生的标记改成了增量更新的方式,使得标记和应用程序交替执行直到标记完成,然后垃圾回收再执行后面的清理工作。注意清理工作并不是增量的。

开发者可以指定强制垃圾回收吗?

答案是可以了,在启动node服务的时候使用--expose-gc flag

$ node --expose-gc file.js

这样全局对象上就有了执行垃圾回收的函数

global.gc();

推荐更安全的写法

function forceGC()
 if (global.gc) {
  global.gc();
 } else {
  console.warn('No GC hook! Start your program as `node --expose-gc file.js`.');
 }
}

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

Vue页面骨架屏注入步骤详解

解决node修改后需频繁手动重启如何处理

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Speicherverwaltungsschritte von Nodejs. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn