I’ve recently been battling with a memory leak that only appears when the system is under heavy load. It turns out that the culprit is XML Serialization. Whenever a type is serialized for the first time, a custom C# class is created and compiled. Provided that you use the right constructor for XmlSerializer this class is supposed to be cached and reused.
Our problem turned out to be that the runtime keeps creating new serialization assemblies for the same type (only under heavy load). I proved this by writing a little application to capture invocations of csc, dump everything to log files and then invoke the real C# compiler so its clients continue to work as normal.
The workaround seems to be to use sgen to create serialization assemblies. That way the runtime should use the one you have prepared rather than writing a new one. There’s a great blog entry here http://www.kiwidude.com/blog/2007/02/vs2005-when-sgen-doesnt-work.html telling you how to do it.
Of course life isn’t quite that simple. The sgen build task doesn’t allow you to specify which types you want to serialize (although there are command line options for this) and by chance there are types in my file that won’t serialize to XML. Nevertheless I’m quietly confident this is going to work…

Addendum:
The problem seems to be caused by the way we were calling a web service proxy.
We had an assembly built for a webservice using svcutil. This doesn’t contain any serialization code. There’s also no way in sgen to build the serializer either. The trick is to use svcutil /t:XmlSerializer to build the serialization code (rather than sgen as you might expect).
Even this wouldn’t have worked for us, becuase the if the serializers aren’t in the same assembly as the contract (which they wouldn’t be), loading the contract won’t automatically load the serializers.
I think this can be overcome by supplying some mechanism to forcibly load the serialization assembly, or by combining the contract and the serializers into the same assembly. Instead we are using a channel factory to create our endpoint proxy, and touch wood, that seems to work.
Hi,
We are also facing the same issue. Do you have the application handy which capture invocations of csc, dump everything to log files?
Thank you.
-Jon Class