我正试图找到客户的VB.NET ASP.NET应用程序中出现内存泄漏的底部(我们没有编写代码)。
有两件事情发生在我身上:
他们有一个带有单个数据访问类的数据访问程序集,在实例化时会在构造函数中运行此代码:
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都显示这是在生产版本构建数据访问程序集中。
使用WinDbg挖掘并执行!dumpheap -stat
我看到了这一点:
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
个对象吗?
/bin
文件夹中的二进制文件是相同的该应用程序使用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/>
。
任何建议都会有用。
答案 0 :(得分:2)
要回答您的第一个问题,弱引用用于保存对象的引用,而不会阻止该对象被垃圾回收。在这种情况下,它们似乎维护了Server类的所有实例的列表。这样的列表需要使用弱引用,否则在创建之后不会删除该类的实例,除非它们首先从该列表中删除。他们正在使用的实例列表我不能说没有看到其余的代码,但他们可能正在进行某种缓存或连接池(虽然后者会很糟糕,因为ado.net已经为你做了这个)。
另外,要知道弱引用本身就是对象,因此除非从列表中删除不再引用活动对象的引用,否则它们将导致内存泄漏。但是,它们是小对象,除非创建了大量的服务器实例,否则不太可能导致问题。
至于你的第二个问题,我不知道这种类型的环境有多少MethodInfo对象是正常的。但是,我确实记得在.Net 2.0时代,在给定的应用程序域中请求后,反射对象永远不会被卸载。据我所知,这没有改变。但是,由于运行时每个唯一方法最多只创建一个这样的对象,除非他们使用某种运行时代码生成,否则这不太可能成为问题。否则,可以创建的此类对象的最大数量将限制为应用程序使用的程序集中的方法数。