Quelle est exactement la limite de mémoire de Node.js ?
La maîtrise de l'API Node.js peut vous permettre d'avancer rapidement, mais une compréhension approfondie de l'empreinte mémoire des programmes Node.js peut vous amener plus loin.
Commençons par jeter un coup d'œil à notre utilisation de la mémoire avec process.memoryUsage(), en mettant à jour toutes les secondes :
setInterval(() => { console.log('Memory Usage:', process.memoryUsage()); }, 1000);
Étant donné que la sortie est en octets, elle n'est pas conviviale. Améliorons-le en formatant l'utilisation de la mémoire en Mo :
function formatMemoryUsageInMB(memUsage) { return { rss: convertToMB(memUsage.rss), heapTotal: convertToMB(memUsage.heapTotal), heapUsed: convertToMB(memUsage.heapUsed), external: convertToMB(memUsage.external) }; } const convertToMB = value => { return (value / 1024 / 1024).toFixed(2) + ' MB'; }; const logInterval = setInterval(() => { const memoryUsageMB = formatMemoryUsageInMB(process.memoryUsage()); console.log(`Memory Usage (MB):`, memoryUsageMB); }, 1000);
Maintenant, nous pouvons obtenir le résultat suivant chaque seconde :
Memory Usage (MB): { rss: '30.96 MB', // The actual OS memory used by the entire program, including code, data, shared libraries, etc. heapTotal: '6.13 MB', // The memory area occupied by JS objects, arrays, etc., dynamically allocated by Node.js // V8 divides the heap into young and old generations for different garbage collection strategies heapUsed: '5.17 MB', external: '0.39 MB' } Memory Usage (MB): { rss: '31.36 MB', heapTotal: '6.13 MB', heapUsed: '5.23 MB', external: '0.41 MB' }
Nous savons tous que l'utilisation de la mémoire du moteur V8 est limitée, non seulement par les politiques de gestion de la mémoire et d'allocation des ressources du système d'exploitation, mais également par ses propres paramètres.
En utilisant os.freemem(), nous pouvons voir la quantité de mémoire libre dont dispose le système d'exploitation, mais cela ne signifie pas que tout est à gagner par un programme Node.js.
console.log('Free memory:', os.freemem());
Pour les systèmes 64 bits, la taille maximale par défaut de l'ancien espace de Node.js V8 est d'environ 1,4 Go. Cela signifie que même si votre système d'exploitation dispose de plus de mémoire disponible, le V8 n'utilisera pas automatiquement plus que cette limite.
Astuce : Cette limite peut être modifiée en définissant des variables d'environnement ou en spécifiant des paramètres lors du démarrage de Node.js. Par exemple, si vous souhaitez que V8 utilise un tas plus grand, vous pouvez utiliser l'option --max-old-space-size :
node --max-old-space-size=4096 your_script.js
Cette valeur doit être définie en fonction de votre situation et de votre scénario réels. Par exemple, si vous disposez d'une machine avec beaucoup de mémoire, déployée de manière autonome, et que vous disposez de nombreuses machines à petite mémoire déployées de manière distribuée, le paramètre de cette valeur sera définitivement différent.
Exécutons un test en remplissant un tableau de données indéfiniment jusqu'à ce que la mémoire déborde et voyons quand cela se produit.
const array = []; while (true) { for (let i = 0; i < 100000; i++) { array.push(i); } const memoryUsageMB = formatMemoryUsageInMB(process.memoryUsage()); console.log(`Memory Usage (MB):`, memoryUsageMB); }
C'est ce que nous obtenons lorsque nous exécutons le programme directement. Après avoir ajouté un peu de données, le programme plante.
Memory Usage (MB): { rss: '2283.64 MB', heapTotal: '2279.48 MB', heapUsed: '2248.73 MB', external: '0.40 MB' } Memory Usage (MB): { rss: '2283.64 MB', heapTotal: '2279.48 MB', heapUsed: '2248.74 MB', external: '0.40 MB' } # # Fatal error in , line 0 # Fatal JavaScript invalid size error 169220804 # # # #FailureMessage Object: 0x7ff7b0ef8070
Vous êtes confus ? La limite n'est-elle pas 1,4G ? Pourquoi utilise-t-il la 2G ? En fait, la limite de 1,4 Go de Node.js est une limite historique du moteur V8, applicable aux premières versions du V8 et à certaines configurations. Dans Node.js et V8 modernes, Node.js ajuste automatiquement son utilisation de la mémoire en fonction des ressources système. Dans certains cas, il peut utiliser bien plus de 1,4 Go, en particulier lorsqu'il s'agit de grands ensembles de données ou d'opérations gourmandes en mémoire.
Lorsque nous définissons la limite de mémoire à 512 Mo, elle déborde lorsque le RSS atteint environ 996 Mo.
Memory Usage (MB): { rss: '996.22 MB', heapTotal: '993.22 MB', heapUsed: '962.08 MB', external: '0.40 MB' } Memory Usage (MB): { rss: '996.23 MB', heapTotal: '993.22 MB', heapUsed: '962.09 MB', external: '0.40 MB' } <--- Last few GCs ---> [22540:0x7fd27684d000] 1680 ms: Mark-sweep 643.0 (674.4) -> 386.8 (419.4) MB, 172.2 / 0.0 ms (average mu = 0.708, current mu = 0.668) allocation failure; scavenge might not succeed [22540:0x7fd27684d000] 2448 ms: Mark-sweep 962.1 (993.2) -> 578.1 (610.7) MB, 240.7 / 0.0 ms (average mu = 0.695, current mu = 0.687) allocation failure; scavenge might not succeed <--- JS stacktrace ---> FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
En résumé, pour être plus précis, la limite de mémoire de Node.js fait référence à la limite de mémoire du tas, qui est la mémoire maximale pouvant être occupée par les objets JS, les tableaux, etc., alloués par la V8.
La taille de la mémoire du tas détermine-t-elle la quantité de mémoire qu'un processus Node.js peut occuper ? Non! Continuez à lire.
Puis-je mettre un fichier de 3 Go dans la mémoire Node.js ?
Nous avons vu lors du test que la baie ne peut contenir qu'un peu plus de 2 Go avant que le programme ne plante. Donc, si j'ai un fichier de 3 Go, ne puis-je pas le mettre d'un seul coup dans la mémoire Node.js ?
Vous pouvez !
Nous avons vu une mémoire externe via process.memoryUsage(), qui est occupée par le processus Node.js mais non allouée par la V8. Tant que vous y placez le fichier de 3 Go, il n'y a pas de limite de mémoire. Comment? Vous pouvez utiliser Buffer. Buffer est un module d'extension C de Node.js qui alloue de la mémoire à l'aide d'objets et de données C, et non JS.
Voici une démo :
setInterval(() => { console.log('Memory Usage:', process.memoryUsage()); }, 1000);
Même si vous allouez 3 Go de mémoire, notre programme fonctionne toujours correctement et notre programme Node.js a occupé plus de 5 Go de mémoire car cette mémoire externe n'est pas limitée par Node.js mais par la limite du système d'exploitation sur la mémoire allouée. aux threads (vous ne pouvez donc pas vous déchaîner, même Buffer peut manquer de mémoire ; l'essence est de gérer des données volumineuses avec Streams).
Dans Node.js, le cycle de vie d'un objet Buffer est lié à un objet JavaScript. Lorsque la référence JavaScript à un objet Buffer est supprimée, le garbage collector V8 marque l'objet comme recyclable, mais la mémoire sous-jacente de l'objet Buffer n'est pas immédiatement libérée. Généralement, lorsque le destructeur de l'extension C est appelé (par exemple, lors du processus de garbage collection dans Node.js), cette partie de la mémoire est libérée. Cependant, ce processus peut ne pas être complètement synchronisé avec le garbage collection de V8.
function formatMemoryUsageInMB(memUsage) { return { rss: convertToMB(memUsage.rss), heapTotal: convertToMB(memUsage.heapTotal), heapUsed: convertToMB(memUsage.heapUsed), external: convertToMB(memUsage.external) }; } const convertToMB = value => { return (value / 1024 / 1024).toFixed(2) + ' MB'; }; const logInterval = setInterval(() => { const memoryUsageMB = formatMemoryUsageInMB(process.memoryUsage()); console.log(`Memory Usage (MB):`, memoryUsageMB); }, 1000);
En résumé : l'utilisation de la mémoire Node.js comprend l'utilisation de la mémoire du tas JS (déterminée par le garbage collection de V8) et l'allocation de mémoire par C
Pourquoi la mémoire tas est-elle séparée en nouvelles et anciennes générations ?
La stratégie générationnelle de garbage collection est très répandue dans les implémentations de langages de programmation modernes ! Des stratégies similaires telles que Generational Garbage Collection peuvent être trouvées dans Ruby, .NET et Java. Lorsque le garbage collection a lieu, cela conduit souvent à une situation « d'arrêt du monde », ce qui a inévitablement un impact sur les performances du programme. Cependant, cette conception est conçue dans un souci d'optimisation des performances.
- Durée de vie des objets divergents Pendant le développement du programme, une partie importante des variables sont temporaires et servent à accomplir des tâches de calcul locales spécifiques. De telles variables conviennent mieux au GC mineur, c'est-à-dire au GC de nouvelle génération. Les objets de la mémoire nouvelle génération sont principalement soumis au garbage collection via l'algorithme Scavenge. L'algorithme Scavenge divise la mémoire du tas en deux parties, à savoir From et To (un compromis espace-temps classique. Grâce à leur courte durée de survie, ils ne consomment pas une grande quantité de mémoire).
Lorsque la mémoire est allouée, elle a lieu dans From. Lors du garbage collection, les objets actifs dans From sont inspectés et copiés vers To, suivis de la libération des objets non actifs. Lors du cycle de collecte suivant, les objets vivants de To sont répliqués vers From, auquel cas To se transforme en From et vice versa. À chaque cycle de garbage collection, From et To sont permutés. Cet algorithme réplique uniquement les objets vivants pendant le processus de copie et évite ainsi la génération de fragments de mémoire.
Alors, comment la vivacité d’une variable est-elle déterminée ? L’analyse d’accessibilité entre en jeu. Considérons les objets suivants à titre d'exemple :
- globalObject : L'objet global.
- obj1 : Un objet directement référencé par globalObject.
- obj2 : Un objet référencé par obj1.
- obj3 : un objet isolé sans aucune référence d'autres objets.
Dans le cadre de l'analyse d'accessibilité :
- globalObject, étant un objet racine, est intrinsèquement accessible.
- obj1, du fait qu'il est référencé par globalObject, est également accessible.
- obj2, tel qu'il est référencé par obj1, est également accessible.
- En revanche, obj3, dépourvu de chemins de référence vers l'objet racine ou d'autres objets accessibles, est jugé inaccessible et donc éligible au recyclage.
Certes, le comptage de références peut servir de moyen auxiliaire. Néanmoins, en présence de références circulaires, il ne parvient pas à déterminer avec précision la véritable vivacité des objets.
Dans la mémoire ancienne génération, les objets sont généralement moins actifs. Cependant, lorsque la mémoire ancienne génération devient pleine, cela déclenche le nettoyage de la mémoire ancienne génération (Major GC) via l'algorithme Mark-Sweep.
L'algorithme Mark-Sweep comprend deux phases : le marquage et le balayage. Lors de la phase de marquage, le moteur V8 parcourt tous les objets du tas et marque ceux qui sont actifs. Lors de la phase de balayage, seuls les objets non marqués sont effacés. Le mérite de cet algorithme est que la phase de balayage prend relativement moins de temps puisque la proportion d'objets morts dans l'ancienne génération est relativement faible. Cependant, son inconvénient est qu'il s'efface uniquement sans compacter, ce qui peut entraîner un espace mémoire discontinu, ce qui rend peu pratique l'allocation de mémoire pour des objets volumineux.
Cette lacune donne lieu à une fragmentation de la mémoire, nécessitant l'emploi d'un autre algorithme, Mark-Compact. Cet algorithme déplace tous les objets vivants vers une extrémité, puis éradique d'un seul coup l'espace mémoire invalide sur le côté droit de la limite, obtenant ainsi un espace mémoire disponible complet et continu. Il résout le problème de fragmentation de la mémoire qui pourrait être causé par l'algorithme Mark-Sweep, mais au prix de plus de temps nécessaire pour déplacer un grand nombre d'objets vivants.
Si vous trouvez cet article utile, merci de lui donner un coup de pouce. :D
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

Video Face Swap
Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

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

Des questions et des solutions fréquemment posées pour l'impression de billets thermiques frontaux pour le développement frontal, l'impression de billets est une exigence commune. Cependant, de nombreux développeurs mettent en œuvre ...

JavaScript est la pierre angulaire du développement Web moderne, et ses principales fonctions incluent la programmation axée sur les événements, la génération de contenu dynamique et la programmation asynchrone. 1) La programmation axée sur les événements permet aux pages Web de changer dynamiquement en fonction des opérations utilisateur. 2) La génération de contenu dynamique permet d'ajuster le contenu de la page en fonction des conditions. 3) La programmation asynchrone garantit que l'interface utilisateur n'est pas bloquée. JavaScript est largement utilisé dans l'interaction Web, les applications à une page et le développement côté serveur, améliorant considérablement la flexibilité de l'expérience utilisateur et du développement multiplateforme.

Il n'y a pas de salaire absolu pour les développeurs Python et JavaScript, selon les compétences et les besoins de l'industrie. 1. Python peut être davantage payé en science des données et en apprentissage automatique. 2. JavaScript a une grande demande dans le développement frontal et complet, et son salaire est également considérable. 3. Les facteurs d'influence comprennent l'expérience, la localisation géographique, la taille de l'entreprise et les compétences spécifiques.

Apprendre JavaScript n'est pas difficile, mais c'est difficile. 1) Comprendre les concepts de base tels que les variables, les types de données, les fonctions, etc. 2) Master la programmation asynchrone et les implémenter via des boucles d'événements. 3) Utilisez les opérations DOM et promettez de gérer les demandes asynchrones. 4) Évitez les erreurs courantes et utilisez des techniques de débogage. 5) Optimiser les performances et suivre les meilleures pratiques.

La discussion sur la réalisation des effets de défilement de parallaxe et d'animation des éléments dans cet article explorera comment réaliser le site officiel de Shiseido (https://www.shiseido.co.jp/sb/wonderland/) ...

Comment fusionner les éléments du tableau avec le même ID dans un seul objet en JavaScript? Lors du traitement des données, nous rencontrons souvent la nécessité d'avoir le même ID ...

Les dernières tendances de JavaScript incluent la montée en puissance de TypeScript, la popularité des frameworks et bibliothèques modernes et l'application de WebAssembly. Les prospects futurs couvrent des systèmes de type plus puissants, le développement du JavaScript côté serveur, l'expansion de l'intelligence artificielle et de l'apprentissage automatique, et le potentiel de l'informatique IoT et Edge.

Discussion approfondie des causes profondes de la différence de sortie Console.log. Cet article analysera les différences dans les résultats de sortie de la fonction Console.log dans un morceau de code et expliquera les raisons derrière. � ...
