Parlons du mécanisme GC (garbage collection) dans Node.js
Comment
Node fait-il le GC (garbage collection) ? L’article suivant vous guidera à travers cela.
GC, Garbage Collection, collecte des déchets. En programmation, il fait généralement référence au mécanisme de recyclage automatique de la mémoire, qui efface régulièrement les données inutiles.
Node.js utilise le moteur V8 en dessous. V8 est un moteur JavaScript hautes performances open source par Google et écrit en C++. [Recommandations du didacticiel associé : Tutoriel vidéo Nodejs]
La mémoire Node.js est principalement divisée en trois parties :
espace de code : où sont stockés les segments de code
pile : variables temporaires générées par l'appel de fonction ; stack, Pour certains types de base, tels que les nombres, les chaînes, les valeurs booléennes et les références d'objet (l'adresse est enregistrée, pas l'objet lui-même).
Heap : stocke des données telles que des objets ;
Heap memory
Node.js utilise V8 en bas. Expliquons le mécanisme de recyclage de la mémoire de V8.
Tout d'abord, tous les objets en JS seront stockés dans la mémoire tas. Lorsque le processus est créé, une taille initiale de mémoire tas sera allouée, puis nos objets y seront placés.
Lorsqu'il y a de plus en plus d'objets, la mémoire du tas ne suffira pas et la mémoire du tas s'étendra dynamiquement. Si une limite maximale est atteinte (généralement 4 Go de nos jours), une erreur de débordement de tas se produit et le processus Node.js est terminé.
Nouvelle génération et ancienne génération
V8 divise d'abord la mémoire en deux parties, ou deux générations :
-
Jeune génération : sauvegarde certains objets avec un temps de survie court
Ancienne génération : sauvegarde les objets qui ont un temps de survie court ; une longue durée de survie ou sont permanents.
La nouvelle génération est très petite et certains objets avec des temps de survie courts sont stockés ici. Ils sont généralement recyclés fréquemment (comme certains objets temporaires dans la pile d'appels de fonctions).
La taille de la nouvelle génération peut être modifiée via
node --max-semi-space-size=SIZE index.js
, en Mo.node --max-semi-space-size=SIZE index.js
修改新生代的大小,单位为 MB。另外,老生代则通过
De plus, l'ancienne génération utilise--max-old-space-size=SIZE
--max-old-space-size=SIZE
pour définir l'algorithme Scavenge de la nouvelle génération
La nouvelle génération utilise l'algorithme Scavenge, qui est un algorithme basé sur la copie.
La nouvelle génération sera divisée en deux espaces. Cet espace est appelé semi-espace. Ils sont :
- Depuis l'espace : les objets nouvellement déclarés seront placés ici
- Vers l'espace : espace utilisé pour la relocalisation
- L'objet nouvellement déclaré sera placé dans l'espace From. Les objets dans l'espace From sont étroitement disposés grâce au pointeur, l'objet précédent est proche de l'objet suivant. La mémoire est continue, il n'y a donc pas lieu de s'inquiéter de la mémoire. fragmentation.
Lorsque l'espace From est presque plein, nous allons parcourir pour trouver les objets actifs et les copier dans l'espace To. À ce stade, l’espace From est en fait vide, puis nous échangeons les identités From et To.
Si certains objets sont copiés plusieurs fois, ils seront considérés comme ayant une durée de survie plus longue et seront déplacés vers l'ancienne génération.
L'avantage de cet algorithme basé sur la copie est qu'il peut très bien gérer le problème de la fragmentation de la mémoire. L'inconvénient est qu'il gaspillera de l'espace en tant qu'espace de déplacement. De plus, comme la copie prend du temps, ce n'est pas le cas. adapté pour allouer un espace mémoire trop grand. Il s'agit plutôt d'un GC auxiliaire.
Mark-Sweep et Mark-CompactL'espace de l'ancienne génération est beaucoup plus grand que celui de la nouvelle génération. Il contient des objets à longue durée de vie et utilise l'algorithme Mark-Sweep (effacement des marques).
La première étape est l’étape de marquage. Recherchez tous les objets accessibles à partir de l'ensemble racine (pile d'exécution et objets globaux) et marquez-les comme objets actifs.
Après le marquage, c'est la phase d'effacement. Effacer les objets non marqués marque en fait l'adresse mémoire comme libre.
Cette approche conduira à une
fragmentation de l'espace mémoire libreLorsque nous créons un grand objet continu, nous ne pourrons pas trouver d'endroit où le poser. À ce stade, Mark-Compact (compactage des marques) doit être utilisé pour intégrer les objets actifs fragmentés. Mark-Compact déplacera toutes les copies d'objets actives vers une extrémité, puis l'autre côté de la limite sera un bloc entier de mémoire disponible contiguë.
Étant donné que Mark-Sweep et Mark-Compact prennent beaucoup de temps et bloquent le fil JavaScript, nous ne le faisons généralement pas en même temps, mais utilisons un marquage incrémentiel (Incremental Marking). Cela signifie marquer par intermittence, procéder par petites étapes et alterner le garbage collection et la logique d'application.
De plus, V8 effectue également un marquage parallèle et un nettoyage parallèle pour améliorer l'efficacité d'exécution.
Afficher les informations relatives à la mémoire
Nous pouvons obtenir des informations relatives à la mémoire grâce à la méthode process.memoryUsage.
process.memoryUsage();
Le contenu de sortie est :
{ rss: 35454976, heapTotal: 7127040, heapUsed: 5287088, external: 958852, arrayBuffers: 11314 }
Instructions
rss : taille de l'ensemble résident (taille de l'ensemble résident), y compris les extraits de code, la mémoire du tas, la pile, etc.
heapTotal : la taille totale de la mémoire du tas de V8 ;
heapUsed : la mémoire du tas occupée
external : la taille de la mémoire autre que V8, qui fait référence à la mémoire occupée par les objets C++ ; Données tampon .
arrayBuffers : La taille de la mémoire liée à
ArrayBuffer
etSharedArrayBuffer
, qui fait partie de l'externe.ArrayBuffer
和SharedArrayBuffer
相关的内存大小,属于 external 的一部分。
以上数字的单位都是字节。
测试最大内存限制
写一个脚本,用一个定时器,让一个数组不停地变大,并打印堆内存使用情况,直到内存溢出。
const format = function (bytes) { return (bytes / 1024 / 1024).toFixed(2) + " MB"; }; const printMemoryUsage = function () { const memoryUsage = process.memoryUsage(); console.log( `heapTotal: ${format(memoryUsage.heapTotal)}, heapUsed: ${format( memoryUsage.heapUsed )}` ); }; const bigArray = []; setInterval(function () { bigArray.push(new Array(20 * 1024 * 1024)); printMemoryUsage(); }, 500);
需要特别注意的是,不要用 Buffer 做测试。
因为 Buffer 是 Node.js 特有的处理二进制的对象,它不是在 V8 中的实现的,是 Node.js 用 C++ 另外实现的,不通过 V8 分配内存,属于堆外内存。
我使用电脑是 macbook pro M1 Pro,Node.js 版本为 v16.17.0
Les unités des nombres ci-dessus sont des octets.
Testez la limite maximale de mémoire
Écrivez un script, utilisez une minuterie, faites croître un tableau en continu et imprimez l'utilisation de la mémoire tas jusqu'à ce que la mémoire déborde.heapTotal: 164.81 MB, heapUsed: 163.93 MB heapTotal: 325.83 MB, heapUsed: 323.79 MB heapTotal: 488.59 MB, heapUsed: 483.84 MB ... heapTotal: 4036.44 MB, heapUsed: 4003.37 MB heapTotal: 4196.45 MB, heapUsed: 4163.29 MB <--- Last few GCs ---> [28033:0x140008000] 17968 ms: Mark-sweep 4003.2 (4036.4) -> 4003.1 (4036.4) MB, 2233.8 / 0.0 ms (average mu = 0.565, current mu = 0.310) allocation failure scavenge might not succeed [28033:0x140008000] 19815 ms: Mark-sweep 4163.3 (4196.5) -> 4163.1 (4196.5) MB, 1780.3 / 0.0 ms (average mu = 0.413, current mu = 0.036) allocation failure scavenge might not succeed <--- JS stacktrace ---> FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory ...
Une attention particulière doit être portée à ne pas utiliser Buffer pour les tests. Parce que Buffer est un objet binaire unique à Node.js. Il n'est pas implémenté dans la V8. Il est implémenté séparément par Node.js en utilisant C++ et n'alloue pas de mémoire via la V8 et appartient à la mémoire hors tas. 🎜🎜L'ordinateur que j'utilise est le macbook pro M1 Pro, la version Node.js est
v16.17.0
et la version V8 utilisée est 9.4.146.26-node.22 (via process. versions.v8 obtenir). 🎜🎜Le résultat de sortie est (certaines informations redondantes sont omises) : 🎜rrreee🎜Comme vous pouvez le voir, la limite de mémoire est dépassée après 4 000 Mo, un débordement de tas se produit et le processus se termine. Notez que sur ma machine, la mémoire maximale par défaut est de 4G. 🎜🎜La mémoire maximale réelle est liée à la machine sur laquelle elle fonctionne. Si la taille de la mémoire de votre machine est de 2 Go, la mémoire maximale sera définie sur 1,5 Go. 🎜🎜Pour plus de connaissances sur les nœuds, veuillez visiter : 🎜tutoriel Nodejs🎜 ! 🎜Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds



PHP et Vue : une combinaison parfaite d'outils de développement front-end À l'ère actuelle de développement rapide d'Internet, le développement front-end est devenu de plus en plus important. Alors que les utilisateurs ont des exigences de plus en plus élevées en matière d’expérience des sites Web et des applications, les développeurs front-end doivent utiliser des outils plus efficaces et plus flexibles pour créer des interfaces réactives et interactives. En tant que deux technologies importantes dans le domaine du développement front-end, PHP et Vue.js peuvent être considérés comme une arme parfaite lorsqu'ils sont associés. Cet article explorera la combinaison de PHP et Vue, ainsi que des exemples de code détaillés pour aider les lecteurs à mieux comprendre et appliquer ces deux éléments.

Avec le développement de la technologie Internet, le développement front-end est devenu de plus en plus important. La popularité des appareils mobiles, en particulier, nécessite une technologie de développement frontal efficace, stable, sûre et facile à entretenir. En tant que langage de programmation en développement rapide, le langage Go est utilisé par de plus en plus de développeurs. Alors, est-il possible d’utiliser le langage Go pour le développement front-end ? Ensuite, cet article expliquera en détail comment utiliser le langage Go pour le développement front-end. Voyons d’abord pourquoi le langage Go est utilisé pour le développement front-end. Beaucoup de gens pensent que le langage Go est un

Lors des entretiens de développement front-end, les questions courantes couvrent un large éventail de sujets, notamment les bases HTML/CSS, les bases JavaScript, les frameworks et les bibliothèques, l'expérience du projet, les algorithmes et les structures de données, l'optimisation des performances, les requêtes inter-domaines, l'ingénierie front-end, les modèles de conception et les nouvelles technologies et tendances. Les questions de l'intervieweur sont conçues pour évaluer les compétences techniques du candidat, son expérience en matière de projet et sa compréhension des tendances du secteur. Par conséquent, les candidats doivent être parfaitement préparés dans ces domaines pour démontrer leurs capacités et leur expertise.

Django est un framework d'application Web écrit en Python qui met l'accent sur un développement rapide et des méthodes propres. Bien que Django soit un framework Web, pour répondre à la question de savoir si Django est un front-end ou un back-end, vous devez avoir une compréhension approfondie des concepts de front-end et de back-end. Le front-end fait référence à l'interface avec laquelle les utilisateurs interagissent directement, et le back-end fait référence aux programmes côté serveur. Ils interagissent avec les données via le protocole HTTP. Lorsque le front-end et le back-end sont séparés, les programmes front-end et back-end peuvent être développés indépendamment pour mettre en œuvre respectivement la logique métier et les effets interactifs, ainsi que l'échange de données.

Golang peut être utilisé comme frontal. Golang est un langage de programmation très polyvalent qui peut être utilisé pour développer différents types d'applications, y compris des applications frontales. En utilisant Golang pour écrire le front-end, vous pouvez vous débarrasser d'un front-end. série de problèmes causés par des langages tels que JavaScript. Par exemple, des problèmes tels qu'une mauvaise sécurité des types, de faibles performances et un code difficile à maintenir.

En tant que développeur C#, notre travail de développement comprend généralement le développement front-end et back-end. À mesure que la technologie se développe et que la complexité des projets augmente, le développement collaboratif du front-end et du back-end est devenu de plus en plus important et complexe. Cet article partagera quelques techniques de développement collaboratif front-end et back-end pour aider les développeurs C# à effectuer leur travail de développement plus efficacement. Après avoir déterminé les spécifications de l’interface, le développement collaboratif du front-end et du back-end est indissociable de l’interaction des interfaces API. Pour assurer le bon déroulement du développement collaboratif front-end et back-end, le plus important est de définir de bonnes spécifications d’interface. La spécification de l'interface implique le nom de l'interface

En tant que langage de programmation rapide et efficace, le langage Go est très populaire dans le domaine du développement back-end. Cependant, peu de gens associent le langage Go au développement front-end. En fait, l’utilisation du langage Go pour le développement front-end peut non seulement améliorer l’efficacité, mais également ouvrir de nouveaux horizons aux développeurs. Cet article explorera la possibilité d'utiliser le langage Go pour le développement front-end et fournira des exemples de code spécifiques pour aider les lecteurs à mieux comprendre ce domaine. Dans le développement front-end traditionnel, JavaScript, HTML et CSS sont souvent utilisés pour créer des interfaces utilisateur.

Les méthodes de mise en œuvre de la messagerie instantanée incluent WebSocket, Long Polling, Server-Sent Events, WebRTC, etc. Introduction détaillée : 1. WebSocket, qui peut établir une connexion persistante entre le client et le serveur pour obtenir une communication bidirectionnelle en temps réel. Le frontal peut utiliser l'API WebSocket pour créer une connexion WebSocket et obtenir une messagerie instantanée en envoyant et en recevant. messages 2. Long Polling, une technologie qui simule la communication en temps réel, etc.
