2016-11-07 5 views
1

Je travaille actuellement sur un projet qui lit un fichier volumineux ou plutôt plusieurs fichiers avec des millions de lignes. Pour ce faire, j'utilise Streamreader pour lire chaque ligne. Chaque ligne est cochée si elle comprend une certaine chaîne. Lorsque la condition est vraie, je vais ajouter une ligne. Je dois reproduire le code de la mémoire puisque je ne le code devant moi:Comment éviter l'utilisation élevée du RAM en ajoutant beaucoup de lignes avec MigraDoc?

Table table = new Table(); 
Row row = new Row(); 
Cell cell = new Cell(); 
using(Streamreader sr = new Streamreader(file)) 
{ 
    string str; 
    while((str = sr.ReadLine()) != null) 
    { 
     if(str.Includes("Marker")) 
     { 
      row = table.AddRow(); 
      cell = row.Cells[0] 
      cell = row.Cells[1] // actually I use a counter variable, cause my table has 6 cells consistent. 
     } 
    } 
} 

Donc, chaque fois que la condition est vraie, un objet ligne sera ajoutée et avec des millions de ces lignes, il y aura aussi des millions d'objets, ce qui affectera ma mémoire de ram et va très probablement «exploser». J'ai essayé plusieurs choses, par exemple créer une liste avec des objets de ligne et les effacer après un certain nombre. Mais j'ai dû comprendre qu'il ne va pas effacer les objets de ram (list.Clear). J'ai essayé d'invoquer le garbage collector manuellement mais cela a une influence négative sur mes performances. Et maintenant, je suis à un point où je ne sais pas comment gérer cela. Avec un demi-million de lignes, il atteint près de 7 Go de RAM et j'ai 8 Go disponibles.

J'apprécierais n'importe quelle suggestion comment je peux éviter le haut bélier ou garder le bélier au moins bas.

Je veux aussi ajouter que je suis nouveau sur stackoverflow et si quelque chose ne se sentent libre clairement l'indiquer ou d'un point sur moi: P

Répondre

2

Vous faites la bonne chose en lisant vos fichiers d'entrée des cours d'eau ligne par ligne. Cela signifie que seule la ligne actuelle de chaque fichier d'entrée doit être présente dans votre RAM. Mais, vous faites la mauvaise chose en mettant une ligne dans votre objet Table pour chaque ligne correspondant au marqueur. Ces objets Table vivent en RAM. Les tentatives de création d'objets Table avec des millions et des millions d'objets Row utiliseront votre RAM, comme vous l'avez découvert.

Les classes de collection dotnet font un bon travail de support de vastes collections. Mais il n'y a pas de magie autour de l'utilisation de la RAM.

Vous devez trouver un moyen de limiter le nombre d'objets Row dans un objet Table. Pouvez-vous garder une trace du nombre de lignes, et quand il atteint un certain nombre (qui sait comment grand? 10K? 100K?) Écrire la table sur le disque et en créer un nouveau?

En outre, il semble que Migradoc génère des fichiers PDF. Un fichier pdf d'un million de pages est-il un objet utile? Cela semble improbable. Idem pour les fichiers RTF.

+0

Merci d'abord pour la réponse rapide. Eh bien, j'ai supposé que ce n'est pas gérable. Je peux garder une trace du nombre de lignes, je vais essayer de mettre en œuvre votre suggestion. Vous pouvez générer des documents rtf avec migradoc également. – kuzurkurt