Thursday, November 20, 2008

.NET XmlSerializer Memory Leak

Production maintenance team reports the memory usage of IIS worker process keeping growing in one high-traffic site, which indicating the memory leak. After investigation, one of culprits is from XmlSerializer:
Type[] relatedTypes = new Type[1];
type[0] = typeof(AppObject);
XmlSerializer serializer = new XmlSerializer(typeof(AppConfig), relatedTypes);
Every time this serializer is created, a dynamic assembly is also generated at run time and is loaded into memory to do the XML serialization. The problem is that once a .NET assembly (dynamic or static) is loaded, there's no way you can clean it through code, and it will only be removed from the memory until the whole application is unloaded. The result is a memory leak with more and more dynamic XML serialization assemblies added into memory.

The solution is use XmlSerialzer constructor with only Type parameter:
XmlSerializer serializer = new XmlSerializer(typeof(object));
Alternative is to cache the XmlSerialzer object for the first time when you can't use such constructor, and reuse it later. In fact .NET caches XmlSerialzer that created only by Type constructor.

This seems to be an known issue. We google it and found many people having same problem. A good article showing the details of tracing this issue can be found here.