XMLSerializer may cause memory leak
XmlSerializer DLL is used to serialize and deserialize types and its widely used in the web service call. Recently in our project implementation I was required to use Solace messaging and was processing the Broadcast message. Since message was in the XML format I need to deserialize the XML to map the data into its corresponding entity. So for mapping this I was deserializing the XML.
Implementation was quite straight forward and it worked fine and was pushed to production server.
XmlSerializer serializer = new XmlSerializer(typeof(ABC), new XmlRootAttribute("XYZ"));
After exactly two days my service crashed and it started throwing Out of Memory exception. I always have a habit of logging in the text file after every function is completed. In logging I noticed that in only particular function its started throwing Memory exception. And after debugging I saw that on the above line of code Memory was increasing and was not disposing. And every time this line of code is called Memory was increasing in folds. After searching in Google I came across excellent MSDN article which gives description for the same. It says try not to use overload of XmlSerializer constructor that takes the XML root element name as its second parameter.
Once a .NET assembly is loaded into memory, it won’t be unloaded until the hosting AppDomain is unloaded. XMLSerializer constructor creates the temporary assembly for the type to be serialized using reflection and since code generation is expensive the assembly is cached in the memory on per type basis. But many times root name will be changed and can be dynamic and it will not cache the dynamic assembly. So whenever the above line of code is called it loads the new assembly every time and will stay in the memory until AppDomain is unloaded. So with this Memory will increase in folds every time its called and Memory is leaked.
So my suggestion is to avoid using the above constructor if possible and if your root element is static than declare XMLSerializer object as a Member variable and initialize it in the constructor. So it will be loaded in the Memory only once and won’t increase the Memory.
And if your root element is dynamic than create once Cache class which will have Dictionary<key,XMLSerializer> and every time a new root element is found we will create the XML serializer object and will store in the Dictionary and next time whenever the same root element is defined we will directly take it from the dictionary. With this it won’t create again and again for the same root element and will have distinct XMLSerializer object.
Hope my above experience helps everyone.
Please do comment if you find this helpful.
Rishi