2

我有内存泄漏,我很难找出问题所在。ASP.NET 进程时不时地增加到 1GB。我已按照此页面 (http://humblecoder.co.uk/tag/windbg) 上的说明进行操作,!gcroot 命令返回以下内容(最后 x 行)。我查看了所有 OracleConnections 和 OracleCommands,它们似乎已正确关闭和处置:

   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
4

1 回答 1

0

如果一段时间后内存使用量下降到 200 MB,这表明您的内存正在被收集,但您仍然可能存在内存误用问题。这个转储没有显示很多,但如果它是在进程为 1GB 时采取的,如你所说,你仍然可以使用它:1)在几个对象上使用 !gcroot,看看它们是如何附加到内存的(我会检查数据库使用情况,似乎你有大量的 oracle 连接(6432),还有很多其他的数据库东西。)像这样:

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

对象将显示内存地址

!gcroot <address>

对象堆栈将显示对象如何附加到内存树。 此过程的示例

2)检查性能计数器(start->run->perfmon)添加这些计数器: - .Net Clr Memory-> #bytes all heaps - Process->private bytes 计算它们之间的差异 - 这是非托管资源消耗的内存(像 DB 客户端对象)在低内存和高内存情况下检查这一点,您将看到内存消耗主要是由于托管内存(所有堆)还是非托管内存。3)如果内存是非托管的,它仍然可能由托管对象持有,因为主应用程序是托管的,因此确保在完成非托管资源后释放它们是关键。(关闭 DBConnections、处理 DBCommands、关闭文件句柄、释放 COMObjects 等)

希望这会有所帮助,阿米特。

于 2012-11-26T07:53:05.680 回答