.net XML序列化程序、新类和数据集出现奇怪的内存泄漏

.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()

我们的应用程序突然启动,内存泄漏。我用以下测试代码成功地复制了它(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()
          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中再次测试它,同样的问题。