2012-07-16 124 views
2

我有一个内存泄漏,我很难找出问题所在。 ASP.NET进程每隔一段时间就提高到1GB。我按照这个页面上的说明(http://humblecoder.co.uk/tag/windbg),!gcroot命令返回以下内容(最后x行)。我已经看过我所有的OracleConnections和OracleCommands,他们似乎是正确闭合并布置:ASP.NET内存泄漏 - OracleCommand对象

6523dfd4  282  28200 System.Data.SqlClient.SqlParameter 
    0e90d850  548  28496 System.IO.MemoryStream 
    67b71a0c  1461  29220 System.Transactions.SafeIUnknown 
    7a5ee588  1924  30784 System.Collections.Specialized.ListDictionary+NodeKeyValueCollection 
    648c91f4  665  31920 System.Configuration.ConfigurationValues 
    7a5e5d04  1342  32208 System.Threading.Semaphore 
    652410f8  670  34840 System.Data.ProviderBase.DbConnectionPool+PoolWaitHandles 
    6613228c  1319  36932 System.Web.Security.FileSecurityDescriptorWrapper 
    66106948  2449  39184 System.Web.UI.AttributeCollection 
    0e8ff780  2021  40420 Microsoft.Win32.SafeHandles.SafeLsaPolicyHandle 
    01e34730  336  43008 Oracle.DataAccess.Client.OracleDataReader 
    648c9434  2218  44360 System.Configuration.ConfigurationValue 
    7a5ea0e4  1918  46032 System.Collections.Specialized.ListDictionary+NodeKeyValueCollection+NodeKeyValueEnumerator 
    7a5eaaa8  3088  49408 System.Collections.Specialized.NameObjectCollectionBase+NameObjectEntry 
    652435c4  1138  59176 System.Data.SqlClient.SqlBuffer 
    0e912c9c  2491  59784 System.Collections.ArrayList 
    0e9132c0  1236  69216 System.Collections.Hashtable 
    6614bf64  45  69660 System.Web.Caching.ExpiresEntry[] 
    0e8ff7d8  4042  80840 Microsoft.Win32.SafeHandles.SafeLsaMemoryHandle 
    66105ff4  5434  86944 System.Web.UI.StateBag 
    01e364c8  5686  90976 Oracle.DataAccess.Client.OpoSqlValTimeoutCtx 
    0e912e08  1007  91556 System.Int32[] 
    7a5ee300  3942  94608 System.Collections.Specialized.ListDictionary+NodeEnumerator 
    01e35ef8  7918  95016 Oracle.DataAccess.Client.OpoSqlRefCtx 
    01e353bc  6043  96688 Oracle.DataAccess.Client.MetaData 
    0e8f83e8  5017  100340 Microsoft.Win32.SafeHandles.SafeLocalAllocHandle 
    7a5ef738  6284  125680 System.Collections.Specialized.HybridDictionary 
    7a5ef7f4  5143  144004 System.Collections.Specialized.ListDictionary 
    661060d0 10908  174528 System.Web.UI.StateItem 
    0e91189c  533  184492 System.Char[] 
    6610d15c  2426  203784 System.Web.UI.WebControls.TableCell 
    01e362ec  7918  221704 Oracle.DataAccess.Client.OracleXmlQueryProperties 
    7a5ef8b4 11231  224620 System.Collections.Specialized.ListDictionary+DictionaryNode 
    65242390  1814  232192 System.Data.SqlClient._SqlMetaData 
    0e8f832c 12124  242480 Microsoft.Win32.SafeHandles.SafeTokenHandle 
    01e36444  7918  253376 Oracle.DataAccess.Client.OracleXmlSaveProperties 
    0e8f7ca8 13394  267880 Microsoft.Win32.SafeHandles.SafeWaitHandle 
    0e9133bc  1255  267912 System.Collections.Hashtable+bucket[] 
    0e8f7a98 12048  289152 System.Threading.ManualResetEvent 
    0e8e443c  7886  385508 System.Object[] 
    01e34b60  6456  387360 Oracle.DataAccess.Client.OpoConRefCtx 
    01e33860  6432  668928 Oracle.DataAccess.Client.OracleConnection 
    01e34f9c  6439  824192 Oracle.DataAccess.Client.OpoConCtx 
    01e34038  7918  1171864 Oracle.DataAccess.Client.OracleCommand 
    000dfbe0  70  5839608  Free 
    0e9136dc  2622  17492932 System.Byte[] 
    0e910c6c 56049  19472876 System.String 
    Total 283875 objects 
+0

包含的堆并不能解释1 GB的内存占用量。记忆峰值时创建的转储吗?如果是这样,你需要寻找其他地方的问题。您是否可以即时生成组件? – 2012-07-19 14:11:15

+0

@Brian Rasmussen,谢谢。我不会即时创建程序集。转储过程在超过1GB时创建。有很多字符串连接。如果56049字符串在内存中可能成为问题,我会游荡吗? – w0051977 2012-07-19 14:25:08

+0

字符串连接可能是个问题,但转储不会显示占用大量内存的大量字符串。所有的.NET进程都会有很多字符串。看着转储字符串似乎不是问题。您可以执行'!eeheap'来检查其他堆。另外,转储文件有多大? – 2012-07-19 14:34:30

回答

0

如果内存使用下降到时间后200 MB,这说明你的内存beeing收集,但你仍然可能有一个记忆错误使用问题。 这个转储没有显示出很多,但是如果在你说的过程是1GB的时候,你仍然可以使用它: 1)在几个对象上使用!gcroot,看看它们是如何连接到内存的将检查数据库的使用,看来你有大量的Oracle连接的(6432),以及很多其他DB的东西飘来飘去) 这样的:

!dumpheap -MT <mt = the left most number> 

对象将显示出与存储器地址

!gcroot <address> 

对象堆栈将显示如何将对象连接到内存树。 a sample of this process

2)检查性能计数器(开始 - >运行>性能监视器)添加这些计数器: - .NET CLR内存 - > #bytes所有堆 - 流程 - >专用字节 计算它们之间的差 - 这是非托管资源消耗的内存(如DB客户端对象) 在低内存和高内存方案中检查此内存,您将看到内存消耗主要是由于托管内存(所有堆)还是非托管内存。 3)如果内存不受管理,它仍然可能由托管对象保存,因为主应用程序是托管的,所以在完成这些操作后确保释放非托管资源是关键。 (关闭DBConnections,处理DBCommands,关闭文件句柄,释放COMObjects等)

希望这会有所帮助, Amit。