为什么这个班级会跟踪弱引用?

时间:2010-11-07 17:22:31

标签: .net asp.net memory-leaks

我正试图找到客户的VB.NET ASP.NET应用程序中出现内存泄漏的底部(我们没有编写代码)。

有两件事情发生在我身上:

  1. 他们有一个带有单个数据访问类的数据访问程序集,在实例化时会在构造函数中运行此代码:

    public SqlServer(string connString)
    {
        List<WeakReference> list = __ENCList;
        lock (list)
        {
            __ENCList.Add(new WeakReference(this));
        }
        // misc other tasks of no further interest
    }
    

    __ENCList在类上声明为:private static List<WeakReference> __ENCList;

    这背后的意图是什么?我确实读过VB.NET使用它来编辑和继续的目的,但是理解它不会在发布版本中生成。 .NET Reflector和ILDASM都显示这是在生产版本构建数据访问程序集中。

  2. 使用WinDbg挖掘并执行!dumpheap -stat我看到了这一点:

  3. 66101820    10269       451836 System.Web.UI.Control+OccasionalFields
    7a5eecbc    22936       458720 System.Collections.Specialized.ListDictionary+DictionaryNode
    79331754     2285       470684 System.Char[]
    648c91f4    10438       501024 System.Configuration.ConfigurationValues
    7a5e9eb0    37978       607648 System.Collections.Specialized.NameObjectCollectionBase+NameObjectEntry
    648c9434    32651       653020 System.Configuration.ConfigurationValue
    7a5e27a0     6567       788040 System.ComponentModel.ReflectPropertyDescriptor
    7932ea08    18318       879264 System.Signature
    79332b54    42528      1020672 System.Collections.ArrayList
    79333178    18348      1027488 System.Collections.Hashtable
    79332cc0     7535      1346108 System.Int32[]
    7932dd5c    43220      2420320 System.Reflection.RuntimePropertyInfo
    7932fde0    72902      4082512 System.Reflection.RuntimeMethodInfo
    79333274    19162      4321680 System.Collections.Hashtable+bucket[]
    79333594     3475      4638780 System.Byte[]
    793042f4   134867      6473100 System.Object[]
    000f6f80      394     24556172      Free
    79330b24   174120     26678884 System.String
    Total 1098618 objects
    Fragmented blocks larger than 0.5 MB:
        Addr     Size      Followed by
    33b7b58c    2.1MB         33d99cf4 System.Data.ProviderBase.DbConnectionClosedBusy
    41635a50    0.6MB         416c873c System.Data.ProviderBase.DbConnectionClosedBusy
    

    这是一个异常多的System.Reflection.RuntimeMethodInfo个对象吗?

    • 服务器有49个站点在单个应用程序池中运行。
    • 所有网站都相同(每个网站都是品牌重塑网站)
    • 每个网站的/bin文件夹中的二进制文件是相同的
    • 服务器正在运行Windows 2003 32位标准SP2
    • 应用程序是用ASP.NET 2.0(Web窗体,而不是MVC)编写的
    • .NET 2.0完全修补到SP2(通过.NET 3.5 SP1更新)。
    • 分页文件设置为增长到4GB(建议最大值我在某处读取)
    • 该应用程序使用Infragistics Web控制套件(v10.2):

      Infragistics35.Web.v10.2.dll
      Infragistics35.WebUI.Shared.v10.2.dll
      Infragistics35.WebUI.UltraWebGrid.v10.2.dll
      Infragistics35.WebUI.UltraWebTab.v10.2.dll
      Infragistics35.WebUI.WebDataInput.v10.2.dll

    当我们看到进程的虚拟字节数达到~2GB且私有字节达到900MB左右时,症状是Out Of Memory异常。

    服务器有<deployment retail="true" /> configured in machine.config`。

    构建版本是debug="false部分中配置的版本构建和<compilation/>

    任何建议都会有用。

1 个答案:

答案 0 :(得分:2)

要回答您的第一个问题,弱引用用于保存对象的引用,而不会阻止该对象被垃圾回收。在这种情况下,它们似乎维护了Server类的所有实例的列表。这样的列表需要使用弱引用,否则在创建之后不会删除该类的实例,除非它们首先从该列表中删除。他们正在使用的实例列表我不能说没有看到其余的代码,但他们可能正在进行某种缓存或连接池(虽然后者会很糟糕,因为ado.net已经为你做了这个)。

另外,要知道弱引用本身就是对象,因此除非从列表中删除不再引用活动对象的引用,否则它们将导致内存泄漏。但是,它们是小对象,除非创建了大量的服务器实例,否则不太可能导致问题。

至于你的第二个问题,我不知道这种类型的环境有多少MethodInfo对象是正常的。但是,我确实记得在.Net 2.0时代,在给定的应用程序域中请求后,反射对象永远不会被卸载。据我所知,这没有改变。但是,由于运行时每个唯一方法最多只创建一个这样的对象,除非他们使用某种运行时代码生成,否则这不太可能成为问题。否则,可以创建的此类对象的最大数量将限制为应用程序使用的程序集中的方法数。