问题
I have a memory leak and I am having a really hard time trying to figure out where the problem is. The ASP.NET process is raising to 1GB every now and then. I have followed the instructions on this page (http://humblecoder.co.uk/tag/windbg) and the !gcroot command returns the following (last x lines). I have looked at all my OracleConnections and OracleCommands and they appear to be closed and disposed correctly:
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
回答1:
If mem usage drops to 200 MB after a time, this shows your memory is beeing collected, but you still might have a memory missuse issue. this dump doesn't show alot, but if it was taken when the process is 1GB as you said, you can still use it: 1) use !gcroot on several objects, to see how they are attached to the memory (i would check the DB usage, it seems you have a large amount of oracle connections (6432), and alot of other DB stuff floating around.) like this:
!dumpheap -MT <mt = the left most number>
objects will show with memory addresses
!gcroot <address>
an object stack will show displaying how the object is attached to the memory tree. a sample of this process
2) check performance counters (start->run->perfmon) add these counters: - .Net Clr Memory-> #bytes all heaps - Process->private bytes calculate the difference between them - this is the memory consumed by unmanaged resources (like DB client objects) check this in low memory and in high memory scenarios, and you will see if the memory consumption is mostly due to Managed memory (all heaps) or unmanaged. 3) if the memory is unmanaged, it's still likely to be held by managed objects, as the main application is managed, so making sure you free unmanaged resources after you are done with them is key. (close DBConnections, dispose DBCommands, close file handles, free COMObjects etc.)
Hope this helps, Amit.
来源:https://stackoverflow.com/questions/11506807/asp-net-memory-leak-oraclecommand-object