.net XML序列化程序、新类和数据集出现奇怪的内存泄漏
我们的应用程序突然启动,内存泄漏。我用以下测试代码成功地复制了它(DotNet 3.5或4.5、visual studio 2013、windows 7/8 64位):.net XML序列化程序、新类和数据集出现奇怪的内存泄漏,.net,class,memory,dataset,xmlserializer,.net,Class,Memory,Dataset,Xmlserializer,我们的应用程序突然启动,内存泄漏。我用以下测试代码成功地复制了它(DotNet 3.5或4.5、visual studio 2013、windows 7/8 64位): 使用新类(即使是空类)类型创建的XMLserializer 一个大循环,创建一个包含一个datatable和一个datacolumn的数据集。 代码如下: Imports System.Xml Imports System.Xml.Serialization Module Module1 Sub Main()
- 使用新类(即使是空类)类型创建的XMLserializer
- 一个大循环,创建一个包含一个datatable和一个datacolumn的数据集。
代码如下:
Imports System.Xml Imports System.Xml.Serialization Module Module1 Sub Main() Dim x As XmlSerializer x = New XmlSerializer(GetType(tClass)) ' needed for reproduce leak Dim ds As DataSet For i As Integer = 0 To 1000000 For j As Integer = 0 To 1000 ds = New DataSet ds.Tables.Add("tb1").Columns.Add("dssd") Next Next End Sub End Module Public Class tClass ' empty class End Class
但是我仍然不知道原因。内存被
XmlSerializer
构造函数中创建的动态生成的运行时程序集占用。从:
动态生成的程序集
为了提高性能,XML序列化基础结构动态生成程序集以序列化和反序列化指定类型
这意味着,第一次为特定类型构造XmlSerializer
时,反射将用于生成c#代码,对该类型和所有引用的类型进行序列化和反序列化,然后链接并加载到内存中。您可以在类中看到执行此操作的参考源代码。加载动态程序集会消耗内存,在卸载之前,不会释放该内存
但是,一旦生成,动态程序集将被缓存,并在以下情况下由运行时重用:
基础结构查找并重用这些程序集。此行为仅在使用以下构造函数时发生:
如果使用任何其他构造函数,将生成同一程序集的多个版本,并且从未卸载,这将导致内存泄漏和性能低下。最简单的解决方案是使用前面提到的两个构造函数之一。否则,必须将程序集缓存在哈希表中
由于正在使用第一个构造函数,因此动态程序集将被缓存和重用,这意味着对于序列化的每个根类型,在应用程序执行期间,内存消耗是一个一次性事件。只要您只序列化有限数量的类型,这些动态程序集使用的内存就有边界,并且可以相当快地稳定下来
(例如,如果您需要序列化数量可能不受限制的类型,那么您的内存使用可能会不断增加。但我怀疑您是否正在这样做。)欢迎使用!考虑清理代码示例的格式,以便人们可以更容易地跟踪它。另外,您如何知道内存泄漏?:)Windows 8中没有内存泄漏。您使用的是什么操作系统?程序运行很长时间,但在任务管理器中内存没有增加。我在Windows 7 Enterprise下测试它,我在64位Windows 7 Enterprise下测试它,Sp1,内存使用在任务管理器中增长非常快,我将尝试在Windows 864位Windows 8.1中再次测试它,同样的问题。