ASP.NET内存泄漏-OracleCommand对象
我有一个内存泄漏,我真的很难找出问题出在哪里。ASP.NET进程有时会提升到1GB。我已按照本页上的说明进行操作http://humblecoder.co.uk/tag/windbg 还有那个!gcroot命令返回以下最后x行。我查看了我的所有OracleConnections和OracleCommand,它们似乎已关闭并正确处置:ASP.NET内存泄漏-OracleCommand对象,asp.net,debugging,windbg,Asp.net,Debugging,Windbg,我有一个内存泄漏,我真的很难找出问题出在哪里。ASP.NET进程有时会提升到1GB。我已按照本页上的说明进行操作http://humblecoder.co.uk/tag/windbg 还有那个!gcroot命令返回以下最后x行。我查看了我的所有OracleConnections和OracleCommand,它们似乎已关闭并正确处置: 6523dfd4 282 28200 System.Data.SqlClient.SqlParameter 0e90d850
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
如果一段时间后内存使用量下降到200 MB,这表明您的内存已被收集,但仍可能存在内存误用问题。 此转储没有显示太多内容,但如果它是在进程为1GB时进行的,如您所说,您仍然可以使用它: 1使用!gcroot在几个对象上,为了查看它们是如何连接到内存的,我会检查数据库的使用情况,似乎您有大量的oracle连接6432,还有很多其他数据库的东西。 像这样:
!dumpheap -MT <mt = the left most number>
对象将显示内存地址
!gcroot <address>
对象堆栈将显示对象是如何连接到内存树的。
2检查性能计数器开始->运行->性能计数器添加这些计数器:
-.Net Clr内存->字节所有堆
-进程->专用字节
计算它们之间的差异-这是非托管资源(如DB客户端对象)消耗的内存
在低内存和高内存场景中检查此项,您将看到内存消耗主要是由于托管内存所有堆还是非托管内存。
3如果内存是非托管的,它仍然可能由托管对象持有,因为主应用程序是托管的,所以确保在使用完非托管资源后释放它们是关键。关闭数据库连接、dispose数据库命令、关闭文件句柄、释放COM对象等
希望这有帮助,
Amit.如果一段时间后内存使用量下降到200 MB,这表明您的内存已被收集,但您仍然可能存在内存误用问题。 此转储没有显示太多内容,但如果它是在进程为1GB时进行的,如您所说,您仍然可以使用它: 1使用!gcroot在几个对象上,为了查看它们是如何连接到内存的,我会检查数据库的使用情况,似乎您有大量的oracle连接6432,还有很多其他数据库的东西。 像这样:
!dumpheap -MT <mt = the left most number>
对象将显示内存地址
!gcroot <address>
对象堆栈将显示对象是如何连接到内存树的。
2检查性能计数器开始->运行->性能计数器添加这些计数器:
-.Net Clr内存->字节所有堆
-进程->专用字节
计算它们之间的差异-这是非托管资源(如DB客户端对象)消耗的内存
在低内存和高内存场景中检查此项,您将看到内存消耗主要是由于托管内存所有堆还是非托管内存。
3如果内存是非托管的,它仍然可能由托管对象持有,因为主应用程序是托管的,所以确保在使用完非托管资源后释放它们是关键。关闭数据库连接、dispose数据库命令、关闭文件句柄、释放COM对象等
希望这有帮助,
Amit.包含的堆不能解释1GB内存占用。是否在内存峰值时创建转储?如果是这样的话,你需要去别处寻找问题。“您是否正在动态生成程序集?”布赖恩·拉斯穆森,谢谢。我不是在动态创建程序集。转储是在进程超过1GB时创建的。有很多字符串连接。我想知道内存中的56049字符串是否会有问题?字符串连接可能会有问题,但转储不会显示大量字符串占用大量内存。所有.NET进程都将有许多字符串。查看转储字符串似乎不是问题所在。你可以做一件事!eeheap检查其他堆。还有,转储文件有多大?@Brian Rasmussen,转储文件是1.3GB。我使用TinyGet对网站进行了压力测试,创建了5个线程和10个循环。我连续做了十次。我的目标网页需要一些时间运行。进程内存增加到900MB,但最后又回落到200MB。这让人困惑。根据你提供的信息,听起来你并没有真正的内存泄漏。如果内存使用率在上升,这可能是由于字符串连接,但由于您说内存使用率再次下降,听起来所有临时字符串实际上都在按预期回收。如果您想减少内存使用,最好使用StringBuilder来处理连接。包含的堆不能解释1GB内存占用。是否在内存峰值时创建转储?如果是这样的话,你需要去别处寻找问题。“您是否正在动态生成程序集?”布赖恩·拉斯穆森,谢谢。我不是在动态创建程序集。转储是在进程超过1GB时创建的。有很多字符串连接。我在徘徊,如果那根绳子
内存中可能存在问题?字符串连接可能存在问题,但转储不会显示大量字符串占用大量内存。所有.NET进程都将有许多字符串。查看转储字符串似乎不是问题所在。你可以做一件事!eeheap检查其他堆。还有,转储文件有多大?@Brian Rasmussen,转储文件是1.3GB。我使用TinyGet对网站进行了压力测试,创建了5个线程和10个循环。我连续做了十次。我的目标网页需要一些时间运行。进程内存增加到900MB,但最后又回落到200MB。这让人困惑。根据你提供的信息,听起来你并没有真正的内存泄漏。如果内存使用率在上升,这可能是由于字符串连接,但由于您说内存使用率再次下降,听起来所有临时字符串实际上都在按预期回收。如果要减少内存使用,最好使用StringBuilder来处理连接。