2017-07-25 2 views
2

J'ai une boucle foreach où je fais quelques opérations avec des images. Je recevais un OutOfMemoryException lors de l'exécution de ce code avec plus de 50 images; car les instances d'image sont chacune de 15 Mo et plus. J'ai supprimé la logique principale car ce problème existe toujours avec ce petit morceau de code. Lorsque j'ajoute GC.Collect(); dans la boucle foreach le problème est parti et je ne reçois pas d'exception.Garbage Collector trop lent dans la boucle foreach?

Ma question est: est-ce que le ramasse-miettes est trop lent pour nettoyer les images qui ne sont plus nécessaires sans appeler la méthode Collect ou est-ce qu'il me manque autre chose?

Je n'ai jamais remarqué ce problème avant. Je n'ai jamais pensé qu'il y aurait un problème parce que la partie //Do some operations a besoin de ~ 1 seconde pour chaque image. Devrait être assez de temps pour le ramasse-miettes que je pensais.

+0

vous n'avez bien pas vraiment le choix si vous obtenez OutOfMemoryExceptions. Aussi que voulez-vous dire par trop lent? –

+0

@PaulF qui n'est pas un doublon. L'OP demande autre chose –

+0

@YvetteColomb: autant que je puisse voir, c'est un doublon - OP souffre de problèmes de mémoire lors de l'utilisation de Bitmaps - car GC ne gère pas automatiquement la mémoire non gérée. La solution donnée répond à la question. Voir aussi la réponse de Romano ci-dessous. – PaulF

Répondre

7

Peut-être que vous devriez travailler avec using:

var files = Directory.GetFiles(path).ToList(); 

foreach (var file in files) 
{ 
    using (Image image = new Bitmap(file)) 
    { 
     // do work 
    } 
} 

De cette façon, le Bitmap sera disposé après l'itération

+0

Merci, j'ai oublié 'Bitmap' et je l'ai éliminé;) –

2

Avez-vous essayé la disposition explicitement l'instance?

var files = Directory.GetFiles(path).ToList(); 
foreach (var file in files) 
{ 
    Image image = new Bitmap(file); 

    //Do some operations 
    image.Dispose(); 
    //image = null; 
} 

La même chose pourrait être mis en œuvre avec using mieux bloc.

1

Le problème n'est pas avec le CPG mais avec l'utilisation de bitmaps. Bien que GC finira par les ramasser, vous avez besoin d'envelopper la création d'images dans using bloc pour assurer leur élimination en temps opportun:

foreach (var file in files) 
{ 
    using (Image image = new Bitmap(file)) { 
     //Do some operations 
    } 
}