4

我正在研究 wcf 应用程序的内存问题,我正在使用 perfview 来挖掘内存。我们得到了一个基本快照,然后是内存高时的快照。我对它们进行了比较,并查看了我看到的未访问内存为 2,921MB 的数据。我的理解是,未到达的内存意味着它已经准备好进行 GC 处理了。已经16个多小时了,无法触及的记忆还在不断攀升。

什么会导致 GC 不收集无法访问的内存?

在此处输入图像描述

更新

当服务消耗大量内存时,我能够获得终结器队列的转储。我究竟应该在这份报告中寻找什么?或者也许我应该运行其他 windbg/sos/sosex 命令?

0:037> !finalizequeue
SyncBlocks to be cleaned up: 0
Free-Threaded Interfaces to be released: 0
MTA Interfaces to be released: 0
STA Interfaces to be released: 0
----------------------------------
------------------------------
Heap 0
generation 0 has 464 finalizable objects (0000000033877190->0000000033878010)
generation 1 has 52 finalizable objects (0000000033876ff0->0000000033877190)
generation 2 has 19958 finalizable objects (0000000033850040->0000000033876ff0)
Ready for finalization 228791 objects (0000000033878010->0000000033a36dc8)
------------------------------
Heap 1
generation 0 has 1508 finalizable objects (000000002ee2e168->000000002ee31088)
generation 1 has 91 finalizable objects (000000002ee2de90->000000002ee2e168)
generation 2 has 23498 finalizable objects (000000002ee00040->000000002ee2de90)
Ready for finalization 249421 objects (000000002ee31088->000000002f0182f0)
------------------------------
Heap 2
generation 0 has 66 finalizable objects (00000000292660d0->00000000292662e0)
generation 1 has 63 finalizable objects (0000000029265ed8->00000000292660d0)
generation 2 has 19411 finalizable objects (0000000029240040->0000000029265ed8)
Ready for finalization 238531 objects (00000000292662e0->00000000294380f8)
------------------------------
Heap 3
generation 0 has 510 finalizable objects (0000000034e470d8->0000000034e480c8)
generation 1 has 77 finalizable objects (0000000034e46e70->0000000034e470d8)
generation 2 has 19910 finalizable objects (0000000034e20040->0000000034e46e70)
Ready for finalization 226933 objects (0000000034e480c8->0000000035003470)
Statistics for all finalizable objects (including all objects ready for finalization):
              MT    Count    TotalSize Class Name
000007fe9c64aba8        1           24 System.Threading.OverlappedDataCache
000007fe9af40ea0        1           24 System.Web.Configuration.ImpersonateTokenRef
000007fea03a8640        1           32 System.IO.Compression.ZLibNative+SafeLibraryHandle
000007fe9dd14820        1           32 Microsoft.Win32.SafeHandles.SafeCspHandle
000007fe9d302a50        1           32 Microsoft.Win32.SafeHandles.SafePEFileHandle
000007fe9cf161a8        1           32 Bid+AutoInit
000007fe9cbead60        1           32 Microsoft.Win32.SafeHandles.SafePerfProviderHandle
000007fe9c69a200        1           32 System.Net.SafeLocalFree
000007fe9c649080        1           32 System.ServiceModel.Channels.PipeHandle
000007fe9c62ad18        1           32 System.Net.SafeInternetHandle
000007fe9af42a08        1           32 Microsoft.Win32.SafeHandles.SafeFileMappingHandle
000007fe9af42920        1           32 Microsoft.Win32.SafeHandles.SafeViewOfFileHandle
000007fe9ad790b0        1           32 System.Web.PerfInstanceDataHandle
000007fe9c4b08d8        1           40 System.Security.SafeBSTRHandle
000007fe9ce69118        1           48 System.Runtime.CompilerServices.ConditionalWeakTable`2[[System.Transactions.ContextKey, System.Transactions],[System.Transactions.ContextData, System.Transactions]]
000007fe9c62cf68        1           48 System.Runtime.IOThreadScheduler
000007fe9af0d5f8        1           48 Microsoft.CSharp.CSharpCodeProvider
000007fe9ae4c628        1           48 System.Runtime.CompilerServices.ConditionalWeakTable`2[[System.Object, mscorlib],[System.Runtime.Serialization.SerializationInfo, mscorlib]]
000007fe9af43750        1           56 System.Web.Compilation.CompilationMutex
000007fe9ae45a60        2           64 System.Security.Cryptography.SafeProvHandle
000007fe9a91bad0        2           64 System.Threading.TimerQueue+AppDomainTimerSafeHandle
000007fea03adee0        2           96 System.Web.Security.FileSecurityDescriptorWrapper
000007fe9d669608        3          120 System.Threading.RegisteredWaitHandleSafe
000007fe9c623850        3          120 System.Net.SafeRegistryHandle
000007fe9c696808        4          128 System.Gen2GcCallback
000007fe9a97d6b0        4          128 Microsoft.Win32.SafeHandles.SafeFileHandle
000007fe9d8710a0        1          160 System.Threading.CdsSyncEtwBCLProvider
000007fe9c64b368        1          160 System.Collections.Concurrent.CDSCollectionETWBCLProvider
000007fe9c648d08        1          160 System.PinnableBufferCacheEventSource
000007fe9be65a08        5          160 Microsoft.Win32.SafeHandles.SafeProcessHandle
000007fe9f557760        1          168 System.Web.AspNetEventSource
000007fe9acab410        2          176 System.Runtime.Diagnostics.EtwProvider
000007fe9ad7daa0        8          192 System.SizedReference
000007fe9aac5d38        2          208 System.Runtime.Remoting.Contexts.Context
000007fe9e5a7c58        1          216 log4net.Appender.RollingFileAppender
000007fe9c64a138        2          224 System.ServiceModel.Channels.OverlappedContext
000007fe9cbe45c8        3          264 System.Diagnostics.PerformanceData.CounterSet
000007fe9cda2278        9          288 System.Net.SafeCloseHandle
000007fe9c628078        6          288 System.Net.SafeCloseSocketAndEvent
000007fe9ad05090        2          320 System.Diagnostics.Tracing.FrameworkEventSource
000007fe9c4be5a0        2          352 System.Data.DataSet
000007fe9c69ee18        3          360 System.Net.TlsStream
000007fe9a97cf10        4          416 System.IO.FileStream
000007fe9a8afc60       14          448 Microsoft.Win32.SafeHandles.SafeRegistryHandle
000007fe9ad05940        6          528 System.Diagnostics.Tracing.EventSource+OverideEventProvider
000007fe9c714d60       18          576 System.Net.SafeFreeContextBuffer_SECURITY
000007fe9c628d68       19          608 System.Net.SafeNativeOverlapped
000007fe9cbe49d8       14          672 System.Diagnostics.PerformanceData.CounterSetInstanceCounterDataSet
000007fe9ae78550       10          720 System.Web.DirMonCompletion
000007fe9cbe4880       14          784 System.Diagnostics.PerformanceData.CounterSetInstance
000007fe9f2d6db8       12          864 NewRelic.Agent.Core.Wrapper.AsyncAgentWrapperApi.Builders.TransactionBuilder
000007fe9bcb8250       27          864 System.Net.SafeCloseSocket+InnerSafeCloseSocket
000007fe9c6947e0        3          888 System.Net.Connection
000007fe9bcb9d18       28         1120 System.Net.SafeCloseSocket
000007fe9ad7bef8       35         1120 Microsoft.Win32.SafeHandles.SafeWaitHandle
000007fe9c2de460        3         1536 System.Data.DataTable
000007fe9c7dee68       62         2480 System.Net.SafeFreeContextBufferChannelBinding_SECURITY
000007fe9cf19418       12         2592 System.Data.DataColumn
000007fe9bcb6b38       28         3808 System.Net.Sockets.Socket
000007fe9c7196c0      120         3840 System.Security.Cryptography.SafeCertChainHandle
000007fe9c695b60       62         3968 System.Net.Sockets.NetworkStream
000007fe9c711618       62         4960 System.Net.Security._SslStream
000007fe9c718cf8      179         7160 System.Net.SafeCredentialReference
000007fe9c74c9d8      240         7680 System.Security.Cryptography.SafeCertStoreHandle
000007fe9d406ff8      377         9048 System.Reflection.Emit.DynamicResolver+DestroyScout
000007fe9dc33bd0      342        10944 System.Security.Cryptography.SafeKeyHandle
000007fe9cda9d00       25        11400 System.Net.Sockets.SocketAsyncEventArgs
000007fe9f4c7440      532        17024 Devart.Common.o
000007fe9f4e2e90      350        22400 Devart.Data.Oracle.OracleCursor
000007fe9c5e4eb8      651        26040 System.Threading.ThreadPoolWorkQueueThreadLocals
000007fe9f448870      792        31680 Microsoft.Practices.EnterpriseLibrary.Caching.Cache
000007fe9f4c5d40      151        41072 Devart.Data.Oracle.a3
000007fe9f4e0fd8      191        41256 Devart.Data.Oracle.OracleDataReader
000007fe9f3ce7d0      191        44312 Devart.Data.Oracle.OracleCommand
000007fe9c661238     1445        46240 System.Security.Cryptography.SafeHashHandle
000007fe9aaa67e0     1985        47640 System.WeakReference
000007fe9ce69d70     2193        70176 System.Transactions.SafeIUnknown
000007fe9c71c040     2593        82976 System.Security.Cryptography.X509Certificates.SafeCertContextHandle
000007fe9a756f58     1932       123648 System.Threading.ReaderWriterLock
000007fe9c74f038     4788       153216 System.Security.Cryptography.SafeLocalAllocHandle
000007fe9c749bf0     5244       167808 System.Security.Cryptography.SafeCertContextHandle
000007fe9a706568     1942       186432 System.Threading.Thread
000007fe9fcf5df0     1692       243648 Devart.Data.Oracle.dz
000007fe9c71c118     6667       320016 System.Net.SafeFreeCredential_SECURITY
000007fe9a9190e0    15031       360744 System.Threading.TimerHolder
000007fe9be64d58     2328       651840 System.Diagnostics.Process
000007fe9f440548    14217      1023624 Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Storage.ConfigurationChangeFileWatcher
000007fe9ce6a6e8    14217      1364832 System.Timers.Timer
000007fe9c71c918    29980      1678880 System.Net.SafeDeleteContext_SECURITY
000007fe9a94dd68    89958      3598320 Microsoft.Win32.SafeHandles.SafeLocalAllocHandle
000007fe9a91b268   185991      5951712 Microsoft.Win32.SafeHandles.SafeTokenHandle
000007fe9ad0b578   206499     14867928 System.Reflection.Emit.DynamicResolver
000007fe9f3ca188   435920     87184000 Devart.Data.Oracle.OracleConnection
Total 1029284 objects

“准备完成”对象的数量对我来说很突出。那不应该是零,或者至少少于几百吗?

4

2 回答 2

3

如果您误用 IDisposable,GC 将不会收集内存。根据您提供的屏幕截图,您
1. 没有关闭与 Oracle 数据库的连接(我说的是 Devart.Data.Oracle.... 片段)。不要依赖于 oracle db 连接的 close 方法,而是考虑使用using运算符,这将为您提供确定性的垃圾收集。
2. 提到 DynamicResolver 的第二行指出了某种依赖注入。根据我的经验,我认为您的依赖注入库不知道如何清理您的对象。这实际上可以通过为您的类实现 IDisposable 接口来解决,这些接口由您的 DI 库使用。
3.第三行,具有以下基因线:win32.safehandles.safetkenhandle给出了暗示您可能使用一些系统资源或外部.NET世界外的东西,这些世界通常也将其命名为无管理的资源。对于他们,您还需要实现内存清理和 IDisposable,但要与 Finalizer 结合使用。有关更多详细信息,请参阅此链接

于 2017-02-16T16:05:43.367 回答
0

已经16个多小时了,无法触及的记忆还在不断攀升。什么会导致 GC 不收集无法访问的内存?

当任何一代中的对象大小运行特定阈值时,GC 将运行。以下是一些近似值:

  • 第 0 代命中 ~256 K
  • 第 1 代命中 ~ 2 MB(收集第 0 代和第 1 代)
  • 第 2 代命中 ~ 10 MB(收集第 0 代、第 1 代和第 2 代)
  • 操作系统发送内存不足通知
  • GC.Collect() 被调用(这不是一个好主意,除非特殊情况)

您的应用程序内存在,2,921MB因此下一次收集暂时不会发生。它是 16 小时还是 1600 小时都没有关系,因为 GC 不是每 x 秒/分钟/小时等运行一次,而是基于上述条件运行。

一个更好的问题要问自己,看看为什么没有在 Gen 0 集合中收集对象。找出哪些对象没有在 Gen 0 中收集,然后问自己:这些对象真的需要存在那么长时间吗?.

  1. 确保在不需要对象时立即处理它们。
  2. 不要将物品放置在需要的时间之外。
于 2017-02-16T16:14:10.193 回答