I've been googling for the past few hours and trying different things but can't seem to the bottom of this....
When I run this code, the memory usage continuously grows.
while (true) { try { foreach (string sym in stringlist) { StreamReader r = new StreamReader(@"C:\Program Files\" + sym + ".xml"); XmlSerializer xml = new XmlSerializer(typeof(XMLObj), new XmlRootAttribute("rootNode")); XMLObj obj = (XMLObj)xml.Deserialize(r); obj.Dispose(); r.Dispose(); r.Close(); } } catch(Exception ex) { Console.WriteLine(ex.ToString()); } Thread.Sleep(1000); Console.Clear(); }
XMLObj is a custom object
[Serializable()] public class XMLObj: IDisposable { [XmlElement("block")] public List<XMLnode> nodes{ get; set; } public XMLObj() { } public void Dispose() { nodes.ForEach(n => n.Dispose()); nodes= null; GC.SuppressFinalize(this); } }
I've tried adding in GC.Collect(); but that doesn't seem to do anything.
Since XmlSerializer is one of the few thread safe classes in the framework you really only need a single instance of each serializer even in a multithreaded application. The only thing left for you to do, is to devise a way to always retrieve the same instance.
XmlSerializer enables you to control how objects are encoded into XML. The XmlSerializer enables you to control how objects are encoded into XML, it has a number of constructors.
The leak is here:
new XmlSerializer(typeof(XMLObj), new XmlRootAttribute("rootNode"))
XmlSerializer
uses assembly generation, and assemblies cannot be collected. It does some automatic cache/reuse for the simplest constructor scenarios (new XmlSerializer(Type)
, etc), but not for this scenario. Consequently, you should cache it manually:
static readonly XmlSerializer mySerializer = new XmlSerializer(typeof(XMLObj), new XmlRootAttribute("rootNode"))
and use the cached serializer instance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With