According to MSDN XmlSerializer Class section "Dynamically Generated Assemblies" the XmlSerializer produces memory leaks when using certain constructors. I wonder if the
XmlSerializer.FromTypes(Type[])
method produces memory leaks, too?
I'm experiencing memory problems, when using the FromTypes
method. So i started some investigations:
for (int i = 0; i < 1000; i++)
{
DummyObject content = new DummyObject()
{
Age = 29,
Location = "London",
Name = "Pete"
};
XmlSerializer serializer = XmlSerializer.FromTypes(new[] { content.GetType() })[0];
using (TextWriter textWriter = new StreamWriter($@"D:\test\array\{i}.xml"))
{
serializer.Serialize(textWriter, content);
}
}
After executing the above code a few times the diagnostic tools of Visual Studio 2015 show the following:
Diagnostic Tools Image
The garbage collector runs, but it seems like the dynamically generated assemblies are flooding the memory. It would be interesting to know which constructor the FromTypes
method internally uses. So, the FromTypes
method produces memory leaks, too?
I slightly changed your code - run a loop 3000 times instead of 1000 and write serialized data into memory stream instead of file, and profile it with dotMemory. (I found using VS that RuntimeType instances are leaked, but did not find how to see where they were created).
At the end app occupied about a 1Mb of memory (I did not received a result of 500Mb as on your screenshot) but it's obviously a leak here.
Then opened all new objects created between the first and the fourth snapshots placed in Gen2 heap and found out that most of them are (as I mentioned above) instances of RuntimeType.
Opened them and saw that there are five almost equal sized groups of them.
So, the answer is "yes, this method produces a memory leak"
Below five stack traces where these objects were allocated
--------- 1 -------------- Allocated: 83580 B in 2985 objects
System.Reflection.Emit.TypeBuilder.CreateTypeNoLock() System.Reflection.Emit.TypeBuilder.CreateType() System.Xml.Serialization.XmlSerializationWriterILGen.GenerateEnd() System.Xml.Serialization.TempAssembly.GenerateRefEmitAssembly() Folded items [AllThreadsRoot]
--------- 2 -------------- Allocated: 83552 B in 2984 objects
System.Reflection.Emit.TypeBuilder.CreateTypeNoLock() System.Reflection.Emit.TypeBuilder.CreateType() System.Xml.Serialization.XmlSerializationReaderILGen.GenerateEnd() System.Xml.Serialization.TempAssembly.GenerateRefEmitAssembly() Folded items [AllThreadsRoot]
--------- 3 -------------- Allocated: 83552 B in 2984 objects
System.Reflection.Emit.TypeBuilder.CreateTypeNoLock() System.Reflection.Emit.TypeBuilder.CreateType() System.Xml.Serialization.XmlSerializationILGen.GenerateBaseSerializer() System.Xml.Serialization.TempAssembly.GenerateRefEmitAssembly() Folded items [AllThreadsRoot]
--------- 4 -------------- Allocated: 83552 B in 2984 objects
System.Reflection.Emit.TypeBuilder.CreateTypeNoLock() System.Reflection.Emit.TypeBuilder.CreateType() System.Xml.Serialization.XmlSerializationILGen.GenerateTypedSerializer() System.Xml.Serialization.TempAssembly.GenerateRefEmitAssembly() Folded items [AllThreadsRoot]
--------- 5 -------------- Allocated: 83552 B in 2984 objects
System.Reflection.Emit.TypeBuilder.CreateTypeNoLock() System.Reflection.Emit.TypeBuilder.CreateType() System.Xml.Serialization.XmlSerializationILGen.GenerateSerializerContract() System.Xml.Serialization.TempAssembly.GenerateRefEmitAssembly() Folded items [AllThreadsRoot]
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