XmlSerializer.FromTypes 产生内存泄漏?
XmlSerializer.FromTypes producing memory leaks?
根据 MSDN XmlSerializer Class 部分 "Dynamically Generated Assemblies",XmlSerializer 在使用某些构造函数时会产生内存泄漏。我想知道
XmlSerializer.FromTypes(Type[])
方法也会产生内存泄漏?
编辑:
我在使用 FromTypes
方法时遇到内存问题。所以我开始了一些调查:
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);
}
}
执行上述代码几次后,Visual Studio 2015 的诊断工具显示如下:
垃圾收集器运行,但似乎动态生成的程序集正在淹没内存。知道 FromTypes
方法内部使用哪个构造函数会很有趣。那么,FromTypes
方法也会产生内存泄漏吗?
我稍微更改了您的代码 - 运行 循环 3000 次而不是 1000 次并将序列化数据写入内存流而不是文件,并使用 dotMemory 对其进行分析。 (我用VS发现RuntimeType实例泄露了,但是没找到怎么查看它们是在哪里创建的)。
最后应用程序占用了大约 1Mb 的内存(我没有收到你屏幕截图上的 500Mb 结果)但它显然是这里的泄漏。
然后打开放置在Gen2堆中的第一个和第四个快照之间创建的所有新对象,发现它们中的大多数是(正如我上面提到的)RuntimeType的实例。
打开一看,有五组,大小差不多。
所以,答案是"yes, this method produces a memory leak"
以下五个堆栈跟踪,其中分配了这些对象
------------ 1------------
已分配:2985 个对象中的 83580 B
System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
System.Reflection.Emit.TypeBuilder.CreateType()
System.Xml.Serialization.XmlSerializationWriterILGen.GenerateEnd()
System.Xml.Serialization.TempAssembly.GenerateRefEmitAssembly()
折叠物品
[AllThreadsRoot]
--------- 2 --------------
已分配:2984 个对象中的 83552 B
System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
System.Reflection.Emit.TypeBuilder.CreateType()
System.Xml.Serialization.XmlSerializationReaderILGen.GenerateEnd()
System.Xml.Serialization.TempAssembly.GenerateRefEmitAssembly()
折叠物品
[AllThreadsRoot]
------------ 3------------
已分配:2984 个对象中的 83552 B
System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
System.Reflection.Emit.TypeBuilder.CreateType()
System.Xml.Serialization.XmlSerializationILGen.GenerateBaseSerializer()
System.Xml.Serialization.TempAssembly.GenerateRefEmitAssembly()
折叠物品
[AllThreadsRoot]
------------ 4 --------------
已分配:2984 个对象中的 83552 B
System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
System.Reflection.Emit.TypeBuilder.CreateType()
System.Xml.Serialization.XmlSerializationILGen.GenerateTypedSerializer()
System.Xml.Serialization.TempAssembly.GenerateRefEmitAssembly()
折叠物品
[AllThreadsRoot]
------------ 5------------
已分配:2984 个对象中的 83552 B
System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
System.Reflection.Emit.TypeBuilder.CreateType()
System.Xml.Serialization.XmlSerializationILGen.GenerateSerializerContract()
System.Xml.Serialization.TempAssembly.GenerateRefEmitAssembly()
折叠物品
[AllThreadsRoot]
根据 MSDN XmlSerializer Class 部分 "Dynamically Generated Assemblies",XmlSerializer 在使用某些构造函数时会产生内存泄漏。我想知道
XmlSerializer.FromTypes(Type[])
方法也会产生内存泄漏?
编辑:
我在使用 FromTypes
方法时遇到内存问题。所以我开始了一些调查:
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);
}
}
执行上述代码几次后,Visual Studio 2015 的诊断工具显示如下:
垃圾收集器运行,但似乎动态生成的程序集正在淹没内存。知道 FromTypes
方法内部使用哪个构造函数会很有趣。那么,FromTypes
方法也会产生内存泄漏吗?
我稍微更改了您的代码 - 运行 循环 3000 次而不是 1000 次并将序列化数据写入内存流而不是文件,并使用 dotMemory 对其进行分析。 (我用VS发现RuntimeType实例泄露了,但是没找到怎么查看它们是在哪里创建的)。
最后应用程序占用了大约 1Mb 的内存(我没有收到你屏幕截图上的 500Mb 结果)但它显然是这里的泄漏。
然后打开放置在Gen2堆中的第一个和第四个快照之间创建的所有新对象,发现它们中的大多数是(正如我上面提到的)RuntimeType的实例。
打开一看,有五组,大小差不多。
所以,答案是"yes, this method produces a memory leak"
以下五个堆栈跟踪,其中分配了这些对象
------------ 1------------ 已分配:2985 个对象中的 83580 B
System.Reflection.Emit.TypeBuilder.CreateTypeNoLock() System.Reflection.Emit.TypeBuilder.CreateType() System.Xml.Serialization.XmlSerializationWriterILGen.GenerateEnd() System.Xml.Serialization.TempAssembly.GenerateRefEmitAssembly() 折叠物品 [AllThreadsRoot]
--------- 2 -------------- 已分配:2984 个对象中的 83552 B
System.Reflection.Emit.TypeBuilder.CreateTypeNoLock() System.Reflection.Emit.TypeBuilder.CreateType() System.Xml.Serialization.XmlSerializationReaderILGen.GenerateEnd() System.Xml.Serialization.TempAssembly.GenerateRefEmitAssembly() 折叠物品 [AllThreadsRoot]
------------ 3------------ 已分配:2984 个对象中的 83552 B
System.Reflection.Emit.TypeBuilder.CreateTypeNoLock() System.Reflection.Emit.TypeBuilder.CreateType() System.Xml.Serialization.XmlSerializationILGen.GenerateBaseSerializer() System.Xml.Serialization.TempAssembly.GenerateRefEmitAssembly() 折叠物品 [AllThreadsRoot]
------------ 4 -------------- 已分配:2984 个对象中的 83552 B
System.Reflection.Emit.TypeBuilder.CreateTypeNoLock() System.Reflection.Emit.TypeBuilder.CreateType() System.Xml.Serialization.XmlSerializationILGen.GenerateTypedSerializer() System.Xml.Serialization.TempAssembly.GenerateRefEmitAssembly() 折叠物品 [AllThreadsRoot]
------------ 5------------ 已分配:2984 个对象中的 83552 B
System.Reflection.Emit.TypeBuilder.CreateTypeNoLock() System.Reflection.Emit.TypeBuilder.CreateType() System.Xml.Serialization.XmlSerializationILGen.GenerateSerializerContract() System.Xml.Serialization.TempAssembly.GenerateRefEmitAssembly() 折叠物品 [AllThreadsRoot]