2017-08-24 2 views
0

Salut J'essaie d'importer une énorme quantité de données. c'est environ 8Go ayant plus de 53k fichiers. Ce que je veux est d'importer un fichier à la fois, fait avec son utilisation, puis supprimer/supprimer ou garbage collecter le cache.Comment effacer/garbage collecter une valeur de variable locale après que son utilisation est terminée

Je sais que lorsque nous utilisons le mot-clé delete, il supprime uniquement la référence de l'instance d'obj. Supprimer ou faire une valeur variable à null ou undefined ne fonctionne pas.

Voici mon code. J'ai essayé tous les moyens possibles pour rendre le cache vide mais pas réussi.

fs.readdir(dirname, (err, filenames) => { 
    if (err) { 
     onError(err); 
     return; 
    } 
    _.forEach(filenames, (file) => { 
     if (!!~file.indexOf('.json')) { 
      this.synchronize(() => { 
       let currentFile = require(`${dirname}${file}`); 
       return new Promise((resolve, reject) => { 
        setTimeout(() => { 
         //assume am done working with the data imported in variable currentFile here. now i want to delete it. 
         resolve('Done'); 
        }, 1) 
       }) 
      }) 
     } 

    }); 
}); 

Y a-t-il un moyen d'effacer le currentFile après avoir fini de travailler dessus?

Ou peut-être comment modifier mon code pour obtenir la fonctionnalité qui fonctionnera pour un certain nombre de fichiers dans le dossier.

toute aide sera appréciée

+0

Essayez d'utiliser 'JSON.parse (fs.readFile (...))' à la place de 'require', qui utilise le cache de module global. Ou effacer ce cache - voir les questions en double. – Bergi

Répondre

1

Je vois 2 gros problèmes avec votre code:

  1. require est capable de charger un fichier JSON qui est ok, mais le principal problème est qu'il le fait de manière synchrone afin vous ne pouvez pas utiliser correctement la nature asynchrone node.js, c'est pourquoi il n'est pas recommandé d'utiliser require pour les fichiers dynamiques, require est destiné à l'initialisation de l'application cause interne il utilise le mécanisme de mise en cache inutile dans votre cas et qui ralentit votre application.
  2. charger et traiter tous les fichiers de cette manière est très consommatrice de ressources et vous devez refactoriser votre architecture en utilisant le stream api c'est le cas d'utilisation où les flux peuvent briller.

Une façon de résoudre votre problème est de plonger dans les éléments suivants aux ressources:

  1. JSONStream module NPM
  2. fs.createReadStream de fs Module

L'idée est de itérer sur tous les les fichiers dans le répertoire que vous êtes en train de faire, puis créez un flux de lecture pour chaque fichier, puis dirigez le JSONStream.parse de cette façon, vous gagnerez énorme quantité de mémoire.

+1

Merci pour la réponse. Je vais refactoriser le code avec vos suggestions. –

+1

Merci beaucoup, 'fs.createReadStream' montre sa magie. –

+0

heureux d'aider @FaheemAlam –

0

Vous ne pouvez pas explicitement dire au garbage collector de libérer un objet. Un objet est détruit dès que le garbage collector réalise qu'il n'y a plus de références à l'objet. Pour ce faire, vous devez vous assurer que toutes les références à l'objet sont supprimées. Tant qu'il y a au moins une référence, l'objet restera en mémoire.

Le moment où vous résolvez la promesse, currentFile n'est plus référencé, et sera finalement recueilli.

+0

Merci pour la réponse, mais pour une raison quelconque, currentFile n'a pas GC. –

+0

Je ne comprends pas. Le GC s'occupera de 'currentFile', pourquoi ne le ferait-il pas? – PeterMader

+0

Je pense que le problème est avec l'importation du fichier en utilisant require. readSteam montre la magie. Merci pour l'aide –