2016-08-11 1 views
4

Je développe une application, qui appelle beaucoup de constructeur XmlSerializer avec un paramètre extraTypes. J'ai découvert, que chaque appel augmente la mémoire de l'application pour environ 100 Ko et 2 descripteurs (parfois plus). Exemple de code:XmlSerializer extraTypes fuite de mémoire

ce code mémoire application encrease pour 100KB et 2 gestionnaires par chaque appel

while (true) 
      { 
       Console.ReadLine(); 
       new XmlSerializer(typeof (object), new Type[] {}); 
      } 

ce code mémoire application encrease pour 43024KB et gestionnaires 2004

for (var i = 0; i < 1000; i++) 
      { 
       new XmlSerializer(typeof (object), new Type[] {}); 
      } 

si juste siplest exemple de console application:

internal class Program 
    { 
     private static void Main(string[] args) 
     { 
      //this code encrease application memory for 43024KB and 2004 handlers 
      for (var i = 0; i < 1000; i++) 
      { 
       new XmlSerializer(typeof (object), new Type[] {}); 
      } 
      Console.WriteLine("Finished. Press any key to continue..."); 


      Console.ReadLine(); 
     } 
    } 

Est-ce un bug dans XmlSerializer ou im faire quelque chose de mal?

P.s. même avec le code optimize sur et une version validée

+0

en double de [fuite de mémoire en utilisant StreamReader et XmlSerializer] (https://stackoverflow.com/questions/23897145/memory-leak-using-streamreader-and-xmlserializer) – dbc

Répondre

4

Ok, il y a déjà une réponse sur msdn https://blogs.msdn.microsoft.com/tess/2006/02/15/net-memory-leak-xmlserializing-your-way-to-a-memory-leak/

réponse Shot est: non, ce n'est pas un bug, il est une caractéristique;)

XmlSerializer crée un TempAssembly pour chaque appel de constructeur avec un paramètre extraTypes. Et "un assembly n'est pas un objet sur le tas GC, le GC est vraiment ignorant des assemblages, donc il ne sera pas récupéré garbage"

Solution est de mettre en cache XmlSerializer dans certains dictionnaire et utiliser un seul objet par type à la place de créer de nouveaux XmlSerializer chaque fois que le besoin d'u il

+0

Oui, Une autre approche consiste à traiter votre code dans le nouveau domaine AppDomain et à décharger appDomain après le traitement. Ainsi, vous vous débarrasserez de ces assemblages temporaires. Juste débogué XmlSerializer et vu exactement ce que vous avez dit dans votre réponse, belle question – ams4fy