C# 使用windbg调试.NET OutOfMemoryException

C# 使用windbg调试.NET OutOfMemoryException,c#,.net,windbg,C#,.net,Windbg,我需要帮助调试.net dll中的OutOfMemoryException,该dll将rtf文本转换为原始文本或html 这是转换的代码,() !!dumpheap-stat命令显示只有2个Mo可用: 00e6a430 865 2382762 Free 以下是perfmon数据: 我不知道如何解决此异常。我尝试添加GC.Collect()来强制GC,但没有任何效果 虚拟机有8个物理内存,在另一个有4个物理内存的虚拟机上,不会发生异常。我不知道如何解决此异常 感谢

我需要帮助调试.net dll中的OutOfMemoryException,该dll将rtf文本转换为原始文本或html

这是转换的代码,()

!!dumpheap-stat命令显示只有2个Mo可用:

00e6a430      865      2382762      Free
以下是perfmon数据:

我不知道如何解决此异常。我尝试添加GC.Collect()来强制GC,但没有任何效果

虚拟机有8个物理内存,在另一个有4个物理内存的虚拟机上,不会发生异常。我不知道如何解决此异常


感谢您的帮助

首先,您很好地提取了所有内部异常,以确定此崩溃是由OOM异常引起的。并非所有的开发人员都具备这种技能

!eeheap-gc
命令显示垃圾收集器使用了4个Mo

这是正确的——这是一个强有力的指标,表明垃圾收集本身并没有真正的帮助。即使它可以释放4MB的内存,您也几乎什么也得不到

(但:稍后将详细介绍)

!dumpheap-stat
命令显示只有2个Mo可用

虽然这句话没有错,但也不完整

a) 有2MB空闲空间,但这2MB被分成865个不同的区域。因此,可能仍然无法分配单个2MB块

b) 从.NET的角度来看,这2MB是免费的。如果.NET没有足够的可用内存,它将从操作系统请求更多内存。然后,该请求可能成功或失败,这取决于操作系统可提供的内存量

有了这些知识,你需要问

为什么操作系统不能给.NET更多的内存

原因很可能是:因为它已经释放了所有的内存。在32位进程中,这是2 GB、3 GB或4 GB,具体取决于配置和设置(主要是大地址感知)。这并不多,尤其是它不能作为一个连续的块使用。在许多情况下,您只有700 MB

操作系统在哪里可以提供内存?在您的案例中添加到COM对象(因为我们有一个COM例外,但这可能会产生误导)。这些COM对象似乎是本机对象(否则它们将分配托管内存)。查看.NET内存将不会有帮助

但是,有一个例外:如果.NET代码是COM对象未被释放的原因,那么.NET代码将间接导致本机内存泄漏。因此,您应该寻找的是RCW对象的数量。如果你有很多,你需要设法摆脱它们

如果这不是原因,可能您的RTF太大,无法容纳最大的可用内存区域

我曾经编了一个故事,告诉你从哪里开始

使用
!address-summary
您可以从操作系统的角度进行查看

您可能有一个较小的
值,因为.NET的使用量很小

如果
Heap
的值较大,则内存将通过Windows堆管理器(例如C++)流失,并且存在本机泄漏(可能是由于COM对象未释放造成的)


您还可以查看“按大小划分的最大区域”一节,在该节中,您将找到
免费
的值。这是一个人通过单个请求可以获得的最大值。也许这还不足以符合您的数据。

,您的数据是什么?另外,您的应用程序是作为32位进程运行还是作为64位进程运行(因为)?我还将留下一个链接,指向我添加的一篇看似有用的博客文章。收集只用于测试,但没有任何效果。这是一个由32位调用的32位dllprocess@user1069516:我已编辑了我的答案,以包含您可能尚未了解的更多信息。
    0:016> !sos.clrstack
OS Thread Id: 0x220c (16)
Child SP       IP Call Site
127beb0c 755bc232 [GCFrame: 127beb0c] 
127bebcc 755bc232 [HelperMethodFrame_2OBJ: 127bebcc] System.Environment.GetResourceFromDefault(System.String)
127bec50 10fa493c System.Environment.GetResourceString(System.String, System.Object[])
127bec60 10fa48af System.Exception.get_Message()
127bec70 069077d9 *** WARNING: Unable to verify checksum for Convertisseur.dll
SQWebContributeur.Convertisseur.Convert.ConvertRtfInSTAThread(System.Object) [D:\SOLU-QIQ\Projets SVN\DLL Maison\Convertisseur\Convertisseur\Convert.cs @ 268]
127bed94 069052d4 System.Threading.ThreadHelper.ThreadStart_Context(System.Object)
127beda0 063e2c17 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
127bee10 063e2177 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
127bee24 06905162 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
127bee3c 069050e3 System.Threading.ThreadHelper.ThreadStart(System.Object)
127bef80 730eebf6 [GCFrame: 127bef80] 
127bf164 730eebf6 [DebuggerU2MCatchHandlerFrame: 127bf164] 


0:016> !pe -nested
Exception object: 019bbfc0
Exception type:   System.Runtime.InteropServices.COMException
    Message:          Espace insuffisant pour traiter cette commande. (Exception de HRESULT : 0x80070008)
InnerException:   <none>
StackTrace (generated):
    SP       IP       Function
    00000000 00000001 UNKNOWN!System.Environment.GetResourceFromDefault(System.String)+0x2
    127BEC50 10FA493C UNKNOWN!System.Environment.GetResourceString(System.String, System.Object[])+0xc
    127BEC60 10FA48AF UNKNOWN!System.Exception.get_Message()+0x4f
    127BEC70 069077D9 Convertisseur_ae70000!SQWebContributeur.Convertisseur.Convert.ConvertRtfInSTAThread(System.Object)+0xe9
    127BED94 069052D4 UNKNOWN!System.Threading.ThreadHelper.ThreadStart_Context(System.Object)+0x9c
    127BEDA0 063E2C17 UNKNOWN!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)+0x107
    127BEE10 063E2177 UNKNOWN!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)+0x17
    127BEE24 06905162 UNKNOWN!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)+0x3a
    127BEE3C 069050E3 UNKNOWN!System.Threading.ThreadHelper.ThreadStart(System.Object)+0x4b

StackTraceString: <none>
HResult: 80070008

Nested exception -------------------------------------------------------------
Exception object: 019b9dc4
Exception type:   System.OutOfMemoryException
Message:          <none>
InnerException:   <none>
StackTrace (generated):
    SP       IP       Function
    00000000 00000001 UNKNOWN!System.GC._WaitForPendingFinalizers()+0x2
    127BEB68 10FA11DF UNKNOWN!System.GC.WaitForPendingFinalizers()+0x4f
    127BEB98 0C55631D Convertisseur_ae70000!SQWebContributeur.ClassesHelp.RtfToHtmlConverter.ConvertRtfToXaml(System.String)+0x385
    127BED00 069078C9 Convertisseur_ae70000!SQWebContributeur.ClassesHelp.RtfToHtmlConverter.ConvertRtfToHtml(System.String)+0x51
    127BED38 0690779C Convertisseur_ae70000!SQWebContributeur.Convertisseur.Convert.ConvertRtfInSTAThread(System.Object)+0xac

StackTraceString: <none>
HResult: 8007000e
0:016> !eeheap -gc
Number of GC Heaps: 1
generation 0 starts at 0x019b9db8
generation 1 starts at 0x019b9cec
generation 2 starts at 0x01861000
ephemeral segment allocation context: none
 segment     begin  allocated      size
01860000  01861000  01bec808  0x38b808(3717128)
Large object heap starts at 0x02861000
 segment     begin  allocated      size
02860000  02861000  028ba260  0x59260(365152)
Total Size:              Size: 0x3e4a68 (4082280) bytes.
------------------------------
GC Heap Size:    Size: 0x3e4a68 (4082280) bytes.
00e6a430      865      2382762      Free