Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XmlSerializer.FromTypes producing memory leaks?

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?

EDIT:

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?

like image 347
ttP Avatar asked Sep 04 '25 16:09

ttP


1 Answers

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. enter image description 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. enter image description here

Opened them and saw that there are five almost equal sized groups of them. enter image description here

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]

like image 138
Ed Pavlov Avatar answered Sep 07 '25 12:09

Ed Pavlov