Je constate que le nombre de descripteurs actifs de mes applications continue d'augmenter. Quel est exactement le nombre de poignées actives? Est-ce quelque chose que je dois faire pour éviter que l'application ne plante?
Un handle est une référence à une ressource ouverte comme un fichier ouvert, une connexion à une base de données ou une demande. Pour comprendre pourquoi les poignées peuvent être actives alors qu'elles auraient dû être fermées, je vous donne un exemple simple:
const http = require('http');
http.createServer((req, res) => {
if (req.url === '/secret-url') {
return; // nobody should have access to this part of our page!
}
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World!');
}).listen(3000);
Que fait ce code? Il exécute un serveur sur le port 3000
et renvoie un Hello World
message pour toute demande, à l'exception de celles qui vont à "l'URL secrète". Mais il y a un problème dans ce code. Lorsque nous rencontrons la clause if "secrète", nous ne fermons jamais la connexion. Cela signifie que le client gardera la connexion ouverte aussi longtemps qu'il le voudra. Nous devrions plutôt fermer la connexion. En faisant cette erreur, le nombre de descripteurs actifs augmentera, ce qui entraînera une fuite de mémoire.
Normalement, les fuites de mémoire sont beaucoup plus difficiles à détecter car les descripteurs actifs peuvent être passés d'une fonction à l'autre, ce qui rend difficile le suivi du code responsable de la fermeture de la connexion.
Si vous voyez une augmentation constante des poignées ouvertes, vous avez très probablement une fuite de mémoire dans votre code quelque part. Comme dans l'exemple, vous avez peut-être oublié de fermer une ressource
Les fuites de mémoire sont en particulier très mauvaises, si vous prévoyez de développer un script qui devrait s'exécuter longtemps, comme un serveur web ...
Il existe différentes techniques pour vérifier les fuites de mémoire. Le moyen le plus simple est évidemment de garder un œil sur la mémoire. pm2 a même une option intégrée pour redémarrer le processus au cas où la mémoire atteindrait un certain point. Pour plus d'informations sur ce sujet, consultez ce guide .
Deux choses. Tout d'abord, les demandes sont très bon marché. Même si vous avez une fuite de mémoire dans votre application serveur Node.js, vous ne commencerez à la voir en mémoire qu'après quelques milliers de requêtes. Contrairement à cela, le marionnettiste coûte très cher. L'ouverture d'un navigateur Chromium vous coûtera de la mémoire entre 50 et 100 mégaoctets. Vous devez donc vous assurer que chaque navigateur que vous démarrez sera fermé. Deuxièmement, comme l'autre réponse déjà mentionnée, il existe des objets (comme elementHandle
) que vous devez supprimer manuellement pour effacer leurs ressources.
Puppeteer a en fait une méthode à utiliser lorsque vous avez terminé avec vos poignées afin que les ramasseurs de déchets puissent faire leur travail. Vous êtes censé utiliser elementHandle.dispose()
comme ceci:
const bodyHandle = await frame.$('body');
const html = await frame.evaluate(body => body.innerHTML, bodyHandle);
// Once you're done with you handle just get rid of it
await bodyHandle.dispose();
Consultez les documents: