Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当你有一个经典的ASP应用程序,它通过互操作使用了大量的.Net时,WinDbg会使用转储文件_.net_Memory Leaks_Asp Classic_Windbg - Fatal编程技术网

当你有一个经典的ASP应用程序,它通过互操作使用了大量的.Net时,WinDbg会使用转储文件

当你有一个经典的ASP应用程序,它通过互操作使用了大量的.Net时,WinDbg会使用转储文件,.net,memory-leaks,asp-classic,windbg,.net,Memory Leaks,Asp Classic,Windbg,好的,首先请不要问为什么这个应用程序是这样的。这是一个典型的ASP应用程序,它在多个领域使用.Net和COM,其中一些.Net也可以访问COM!这一切都与代码重用有关真的,在某个时候.Net被引入并用于一系列功能,这些功能在经典的ASP应用程序和voile中都是必需的!某种地狱般的野兽出现了 那我的问题呢?我可以看到应用程序中出现了严重的内存泄漏(32位),私有字节将突然增加到900mb以上,用户将开始收到内存不足错误和一些奇怪的问题,如正在呈现的部分页面。最初,我只是获取一些perfmon日志

好的,首先请不要问为什么这个应用程序是这样的。这是一个典型的ASP应用程序,它在多个领域使用.Net和COM,其中一些.Net也可以访问COM!这一切都与代码重用有关真的,在某个时候.Net被引入并用于一系列功能,这些功能在经典的ASP应用程序和voile中都是必需的!某种地狱般的野兽出现了

那我的问题呢?我可以看到应用程序中出现了严重的内存泄漏(32位),私有字节将突然增加到900mb以上,用户将开始收到内存不足错误和一些奇怪的问题,如正在呈现的部分页面。最初,我只是获取一些perfmon日志,添加一些用户操作跟踪代码,并将跟踪中的数据绑定到perfmon(w3wp上的工作集和私有字节)。这告诉了我一些事情,我确实发现了“解决”和发布的问题——尽管它们没有影响。基于IIS日志中的操作对应用程序进行的压力测试也没有告诉我什么——我根本无法在本地复制

因此,当它达到900mb左右时,我得到了一个内存转储,我正在使用WinDbg进行分析。问题是——我过去几乎没有使用过这个工具,而我这么做是很久以前的事了。我做了一些事情,比如:

.loadby sos mscorwks
!dumpheap -stat
我将System.String作为内存的最大用户,并将所有字符串转储到控制台,但这是毫无意义的,只是我可能希望看到的一堆字符串。我看不见树林,看不见树木

有人对我如何解释dmp文件并确定什么真正占用了大部分内存有什么建议吗?事实上System.String“似乎”正在使用它的大部分内容(它位于底部),我相信这并不完全正确。这也不是严格意义上的.Net应用程序,因此我如何知道.Net或经典ASP/COM是否占用了大部分内存

更新1

多谢托马斯和亚历克斯的回答。我正在努力寻找根本原因,但已经深入到了一点,我看到一个共同的模式/主题正在出现。请参见以下内容:

我查找内存使用情况的摘要:

>!heap -s
 Heap     Flags   Reserv  Commit  Virt   Free  List   UCR  Virt  Lock  Fast 
                    (k)     (k)    (k)     (k) length      blocks cont. heap 
-----------------------------------------------------------------------------
002a0000 58001062  695360 677844 680772   2102   100   420    8  1f960   L  
我对结果进行了修改,以显示其中一个,但头部的大部分内存显然都被这个地址使用。 然后我查看该地址,可以看到大多数对象的大小为2404,因此我查看这些对象是什么:

>!heap -stat -h 002a0000
size     #blocks     total     ( %) (percent of total busy bytes)
2404 cfce - 1d3c3738  (71.05)
>!heap -flt s 2404
按照预期返回一个非常大的列表,通过确保w3wp的+ust gflags处于打开状态,然后收集转储并调查其中的一些,我得到了一个相当描述性的堆栈跟踪:

>!heap -p -a 4fc4d7b8
 HEAP_ENTRY Size Prev Flags    UserPtr UserSize - state
    4fc4d7b0 0484 0000  [07]   4fc4d7b8    02404 - (busy)
    Trace: 414f
    7c833ba5 ntdll!RtlInitializeCriticalSection+0x00000010
    77e67877 kernel32!InitializeCriticalSection+0x0000000e
    79e8539b mscorwks!CrstBase::InitWorker+0x000000a7
    79e853d4 mscorwks!Crst::Crst+0x00000016
    79e92b58 mscorwks!PendingTypeLoadEntry::PendingTypeLoadEntry+0x0000001c
    79e92992 mscorwks!ClassLoader::LoadTypeHandleForTypeKey_Inner+0x000000bd
    79e92b01 mscorwks!ClassLoader::LoadTypeHandleForTypeKey_Body+0x000001da
    79e9272a mscorwks!ClassLoader::LoadTypeHandleForTypeKey+0x000000ae
    79e9359f mscorwks!ClassLoader::EnsureLoaded+0x000000a6
    79e932d9 mscorwks!MethodTable::DoFullyLoad+0x000000c1
    79e9302f mscorwks!MethodTable::DoFullyLoad+0x00000180
    79e9333c mscorwks!MethodTable::DoFullyLoad+0x00000142
    79e92dc9 mscorwks!ClassLoader::Notify+0x00000104
    79e92764 mscorwks!ClassLoader::LoadTypeHandleForTypeKey+0x000000e8
    79e934b3 mscorwks!ClassLoader::LoadTypeDefThrowing+0x00000193
    79e94515 mscorwks!ClassLoader::LoadTypeHandleThrowing+0x000001f4
    79e8c1f0 mscorwks!ClassLoader::LoadTypeHandleThrowIfFailed+0x0000001b
    79efd389 mscorwks!ClassLoader::LoadTypeByNameThrowing+0x0000003b
    79efd315 mscorwks!Binder::LookupClass+0x00000032
    79efd3ab mscorwks!Binder::FetchClass+0x0000001f
    79f1ec2b mscorwks!RefSecContext::Init+0x000000ba
    79ef3726 mscorwks!RuntimeTypeHandle::CreateInstance+0x00000334
    7d0663a +0x07d0663a
    7d06567 +0x07d06567
    7d063b5 +0x07d063b5
    7d05ec3 +0x07d05ec3
    7d05e60 +0x07d05e60
    7d05e22 +0x07d05e22
    7d05dda +0x07d05dda
    7d05cbe +0x07d05cbe
    7d05c44 +0x07d05c44
    7d0582d +0x07d0582d


此时,我希望能够准确地看到正在实例化的类,从而给我一个线索,即哪个用户操作(总是从经典的ASP页面)正在调用什么(例如,cASP调用COM或.Net,而后者又可以调用COM或.Net)

您需要找到在内存中保存这些字符串的根。在我的文章中,我有几个例子:但通常您可能需要做的是使用
!gcroot
命令-它应该将对象图遍历到保存此对象的根之一。

有两种不同的堆类型:本机堆(堆管理器的堆)和托管堆(由.NET运行时创建的堆)。您看到的是
的输出!dumpheap
只是托管部分。由于COM对象也使用本机内存,因此输出中不包括本机内存

要查看内存的本机部分,请尝试
!地址-摘要
。NET内存将显示为
,本机内存将在使用情况摘要中列为

不过,
!dumpheap
可能会有所帮助,例如查看应用程序创建的RCW对象的数量。RCW不是很大,因此它们可能不会列在输出末尾附近。试试
!dumpheap-stat-type Interop
查找它们(如果您使用的是默认的Interop程序集)

如果您知道COM对象在本机端的大小,您可以将对象的数量乘以内存使用量。在我的典型环境中,我使用的是大小为5 MB到100 MB的不同COM对象,因此即使是少数COM对象也可能导致
OutOfMemoryException


了解COM对象的确切大小有助于使用它。

谢谢,我收到一个错误!地址-摘要>“当前目标没有提供完整的内存信息。没有可用的有意义的摘要…等等”。所以我试过了!解决问题,但在现阶段,结果看起来不太有用。对名为“Interop”的类型进行过滤非常有用,它至少可以确认这些对象中有许多正在使用,例如,使用1232字节的77个集合包装器似乎正在使用,但这还远远不够导致问题(imho)。我想知道您是否对我在更新1中的新发现有什么想法?@MrAH:为了进行良好的.NET分析,您总是需要一个内存充足的转储,即WinDbg中的
/ma
,或Procdump中的
-ma
,或使用Process Explorer。你是怎么倒垃圾的?您能否键入
.dumpdebug
并在输出的最开始处张贴标志?它应该包含类似以下内容:
MiniDumpWith…
。这些内容是用procdump-ma获取的,它在.dumpdebug命令后给出了以下标志:flags 26 0002 MiniDumpWithFullMemory 0004 MiniDumpWithHandleData 0020 minidumpWithUnloadedModules这是一个很好的提议,但我担心这是一个实时客户系统,内存中保存着我无法共享的敏感字符串数据。目前令人沮丧的是,这些2404大小的堆中许多对象的堆栈跟踪告诉我所使用的类型。我本以为地址在
79ef3726 mscorwks!RuntimeTypeHandle::CreateInstance+0x00000334
> !heap -p -a 4fca7ff0
address 4fca7ff0 found in
_HEAP @ 2a0000
  HEAP_ENTRY Size Prev Flags    UserPtr UserSize - state
    4fca7fe8 0484 0000  [07]   4fca7ff0    02404 - (busy)
    Trace: 414b
    7c854f44 ntdll!RtlAllocateHeapSlowly+0x00000041
    7c83d7f0 ntdll!RtlAllocateHeap+0x00000e9f
    79e747ac mscorwks!EEHeapAlloc+0x00000142
    79e7482a mscorwks!EEHeapAllocInProcessHeap+0x00000052
    79e74853 mscorwks!operator new[]+0x00000025
    79e927d9 mscorwks!PendingTypeLoadTable::AllocNewEntry+0x0000000c
    79e929ae mscorwks!ClassLoader::LoadTypeHandleForTypeKey_Inner+0x000000d9
    79e92b01 mscorwks!ClassLoader::LoadTypeHandleForTypeKey_Body+0x000001da
    79e9272a mscorwks!ClassLoader::LoadTypeHandleForTypeKey+0x000000ae
    79e9359f mscorwks!ClassLoader::EnsureLoaded+0x000000a6
    79e92faa mscorwks!ClassLoader::LoadExactParentAndInterfacesTransitively+0x000000c2
    79e92fe7 mscorwks!ClassLoader::LoadExactParents+0x00000027
    79e92f24 mscorwks!ClassLoader::DoIncrementalLoad+0x00000057
    79e929e1 mscorwks!ClassLoader::LoadTypeHandleForTypeKey_Inner+0x0000012c
    79e92b01 mscorwks!ClassLoader::LoadTypeHandleForTypeKey_Body+0x000001da
    79e9272a mscorwks!ClassLoader::LoadTypeHandleForTypeKey+0x000000ae
    79e934b3 mscorwks!ClassLoader::LoadTypeDefThrowing+0x00000193
    79e94515 mscorwks!ClassLoader::LoadTypeHandleThrowing+0x000001f4
    79e8c1f0 mscorwks!ClassLoader::LoadTypeHandleThrowIfFailed+0x0000001b
    79efd389 mscorwks!ClassLoader::LoadTypeByNameThrowing+0x0000003b
    79efd315 mscorwks!Binder::LookupClass+0x00000032
    79efd3ab mscorwks!Binder::FetchClass+0x0000001f
    79f1ec2b mscorwks!RefSecContext::Init+0x000000ba
    79ef3726 mscorwks!RuntimeTypeHandle::CreateInstance+0x00000334
    7d0663a +0x07d0663a
    7d06567 +0x07d06567
    7d063b5 +0x07d063b5
    7d05ec3 +0x07d05ec3
    7d05e60 +0x07d05e60
    7d05e22 +0x07d05e22
    7d05dda +0x07d05dda
    7d05cbe +0x07d05cbe