The problem is not new: it is well documented (section Dynamically Generated Assemblies) and there are numerous forum and blog posts about it; but still, I bumped on it again a few days ago. Some of .NET’s
XmlSerializer constructors may lead to memory leaks and serious performance issues.
As stated on MSDN,
XmlSerializer dynamically generates assemblies to serialize and deserialize specified types. However, only
XmlSerializer.XmlSerializer(Type, String) constructors cache the generated assemblies. The other constructors don’t (namely the one that has a
XmlRootAttribute argument). If one is creating different instances of a serializer using one of the non-cached constructors, they keep generating assemblies that are never unloaded, resulting on memory leaks. Also, the performance penalty is significant (around 100 ms in my scenario, where a rather simple object graph was being serialized). The post I mentioned above goes further the reasons for these issues.
A possible solution, as suggested on MSDN, is to cache the serializers accordingly to the
XmlRootAttribute in use. Nevertheless, there’s is an important aspect that may avoid some problems:
XmlSerializer is thread-safe. In many cases just sharing a static instance among different requests (or threads) might do the trick.