使用 Windbg 调试 .NET OutOfMemoryException

2024-02-16

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

这是转换代码,(http://matthewmanela.com/blog/converting-rtf-to-html/ http://matthewmanela.com/blog/converting-rtf-to-html/)

public string ConvertRtfToHtml(string rtfText)
{
    if (rtfText.Equals("")) return "";
    try
    {
        var thread = new Thread(ConvertRtfInSTAThread);
        var threadData = new ConvertRtfThreadData { RtfText = rtfText };
        thread.SetApartmentState(ApartmentState.STA);
        thread.Start(threadData);
        thread.Join();

        return threadData.HtmlText;
    }
    catch (Exception e)
    {
        GestionErreurConv.EnregistrerErreur("Convert", "ConvertRtfToHtml", e.Message);
        return rtfText;
    }
}

private void ConvertRtfInSTAThread(object rtf)
{
    try
    {
        var threadData = (ConvertRtfThreadData)rtf;
        var converter = new RtfToHtmlConverter();
        threadData.HtmlText = converter.ConvertRtfToHtml(threadData.RtfText);
    }
    catch (Exception e)
    {
        GestionErreurConv.EnregistrerErreur("Convert", "ConvertRtfToHtml", e.Message);
    }
}

public class RtfToHtmlConverter
{
    private const string FlowDocumentFormat = "<FlowDocument>{0}</FlowDocument>";

    public string ConvertRtfToHtml(string rtfText)
    {
        var xamlText = string.Format(FlowDocumentFormat, ConvertRtfToXaml(rtfText));
        var converter = new HtmlFromXamlConverter();
        return converter.ConvertXamlToHtml(xamlText, false);
    }

    private string ConvertRtfToXaml(string rtfText)
    {
        string returnString;

        try
        {
            var richTextBox = new RichTextBox
            {
                UndoLimit = 0,
                IsUndoEnabled = false
            };

            var textRange = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);

            //Create a MemoryStream of the Rtf content
            using (var rtfMemoryStream = new MemoryStream())
            {
                using (var rtfStreamWriter = new StreamWriter(rtfMemoryStream))
                {
                    rtfStreamWriter.Write(rtfText);
                    rtfStreamWriter.Flush();
                    rtfMemoryStream.Seek(0, SeekOrigin.Begin);

                    //Load the MemoryStream into TextRange ranging from start to end of RichTextBox.
                    textRange.Load(rtfMemoryStream, DataFormats.Rtf);
                }
            }

            using (var rtfMemoryStream = new MemoryStream())
            {
                textRange = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);
                textRange.Save(rtfMemoryStream, DataFormats.Xaml);
                rtfMemoryStream.Seek(0, SeekOrigin.Begin);
                using (var rtfStreamReader = new StreamReader(rtfMemoryStream)) { 
                    returnString = rtfStreamReader.ReadToEnd();
                }
            }

            // Libération mémoire
            GC.Collect();
            GC.WaitForPendingFinalizers();

            return returnString;
        }
        catch (Exception)
        {
            // Libération mémoire
            GC.Collect();
            GC.WaitForPendingFinalizers();
            return rtfText;
        }
    }
}

/// <summary>
/// HtmlToXamlConverter is a static class that takes an HTML string
/// and converts it into XAML
/// </summary>
public class HtmlFromXamlConverter
{
    #region Public Methods

    /// <summary>
    /// Main entry point for Xaml-to-Html converter.
    /// Converts a xaml string into html string.
    /// </summary>
    /// <param name="xamlString">
    /// Xaml strinng to convert.
    /// </param>
    /// <returns>
    /// Html string produced from a source xaml.
    /// </returns>
    public string ConvertXamlToHtml(string xamlString, bool asFullDocument)
    {
        var htmlStringBuilder = new StringBuilder(100);

        using (var xamlReader = new XmlTextReader(new StringReader(xamlString)))
        using (var htmlWriter = new XmlTextWriter(new StringWriter(htmlStringBuilder)))
        {
            if (!WriteFlowDocument(xamlReader, htmlWriter, asFullDocument))
            {
                return "";
            }

            return htmlStringBuilder.ToString();
        }
    }

    #endregion Public Methods

    // ---------------------------------------------------------------------
    //
    // Private Methods
    //
    // ---------------------------------------------------------------------

    #region Private Methods
    /// <summary>
    /// Processes a root level element of XAML (normally it's FlowDocument element).
    /// </summary>
    /// <param name="xamlReader">
    /// XmlTextReader for a source xaml.
    /// </param>
    /// <param name="htmlWriter">
    /// XmlTextWriter producing resulting html
    /// </param>
    private bool WriteFlowDocument(XmlTextReader xamlReader, XmlTextWriter htmlWriter, bool asFullDocument)
    {
        if (!ReadNextToken(xamlReader))
        {
            // Xaml content is empty - nothing to convert
            return false;
        }

        if (xamlReader.NodeType != XmlNodeType.Element || xamlReader.Name != "FlowDocument")
        {
            // Root FlowDocument elemet is missing
            return false;
        }

        // Create a buffer StringBuilder for collecting css properties for inline STYLE attributes
        // on every element level (it will be re-initialized on every level).
        var inlineStyle = new StringBuilder();

        if (asFullDocument)
        {
            htmlWriter.WriteStartElement("HTML");
            htmlWriter.WriteStartElement("BODY");
        }

        WriteFormattingProperties(xamlReader, htmlWriter, inlineStyle);

        WriteElementContent(xamlReader, htmlWriter, inlineStyle);

        if (asFullDocument)
        {
            htmlWriter.WriteEndElement();
            htmlWriter.WriteEndElement();
        }
        return true;
    }

    /// <summary>
    /// Reads attributes of the current xaml element and converts
    /// them into appropriate html attributes or css styles.
    /// </summary>
    /// <param name="xamlReader">
    /// XmlTextReader which is expected to be at XmlNodeType.Element
    /// (opening element tag) position.
    /// The reader will remain at the same level after function complete.
    /// </param>
    /// <param name="htmlWriter">
    /// XmlTextWriter for output html, which is expected to be in
    /// after WriteStartElement state.
    /// </param>
    /// <param name="inlineStyle">
    /// String builder for collecting css properties for inline STYLE attribute.
    /// </param>
    private void WriteFormattingProperties(XmlTextReader xamlReader, XmlTextWriter htmlWriter, StringBuilder inlineStyle)
    {
        // Clear string builder for the inline style
        inlineStyle.Remove(0, inlineStyle.Length);

        if (!xamlReader.HasAttributes)
        {
            return;
        }

        bool borderSet = false;

        while (xamlReader.MoveToNextAttribute())
        {
            string css = null;

            switch (xamlReader.Name)
            {
                // Character fomatting properties
                // ------------------------------
                case "Background":
                    css = "background-color:" + ParseXamlColor(xamlReader.Value) + ";";
                    break;
                case "FontFamily":
                    css = "font-family:" + xamlReader.Value + ";";
                    break;
                case "FontStyle":
                    css = "font-style:" + xamlReader.Value.ToLower() + ";";
                    break;
                case "FontWeight":
                    css = "font-weight:" + xamlReader.Value.ToLower() + ";";
                    break;
                case "FontStretch":
                    break;
                case "FontSize":
                    css = "font-size:" + xamlReader.Value + "px;";
                    break;
                case "Foreground":
                    css = "color:" + ParseXamlColor(xamlReader.Value) + ";";
                    break;
                case "TextDecorations":
                    if (xamlReader.Value.ToLower() == "strikethrough")
                        css = "text-decoration:line-through;";
                    else
                        css = "text-decoration:underline;";
                    break;
                case "TextEffects":
                    break;
                case "Emphasis":
                    break;
                case "StandardLigatures":
                    break;
                case "Variants":
                    break;
                case "Capitals":
                    break;
                case "Fraction":
                    break;

                // Paragraph formatting properties
                // -------------------------------
                case "Padding":
                    css = "padding:" + ParseXamlThickness(xamlReader.Value) + ";";
                    break;
                case "Margin":
                    css = "margin:" + ParseXamlThickness(xamlReader.Value) + ";";
                    break;
                case "BorderThickness":
                    css = "border-width:" + ParseXamlThickness(xamlReader.Value) + ";";
                    borderSet = true;
                    break;
                case "BorderBrush":
                    css = "border-color:" + ParseXamlColor(xamlReader.Value) + ";";
                    borderSet = true;
                    break;
                case "LineHeight":
                    break;
                case "TextIndent":
                    css = "text-indent:" + xamlReader.Value + ";";
                    break;
                case "TextAlignment":
                    css = "text-align:" + xamlReader.Value + ";";
                    break;
                case "IsKeptTogether":
                    break;
                case "IsKeptWithNext":
                    break;
                case "ColumnBreakBefore":
                    break;
                case "PageBreakBefore":
                    break;
                case "FlowDirection":
                    break;

                // Table attributes
                // ----------------
                case "Width":
                    css = "width:" + xamlReader.Value + ";";
                    break;
                case "ColumnSpan":
                    htmlWriter.WriteAttributeString("COLSPAN", xamlReader.Value);
                    break;
                case "RowSpan":
                    htmlWriter.WriteAttributeString("ROWSPAN", xamlReader.Value);
                    break;

                // Hyperlink Attributes
                case "NavigateUri":
                    htmlWriter.WriteAttributeString("HREF", xamlReader.Value);
                    break;

                case "TargetName":
                    htmlWriter.WriteAttributeString("TARGET", xamlReader.Value);
                    break;
            }

            if (css != null)
            {
                inlineStyle.Append(css);
            }
        }

        if (borderSet)
        {
            inlineStyle.Append("border-style:solid;mso-element:para-border-div;");
        }

        // Return the xamlReader back to element level
        xamlReader.MoveToElement();
    }

    private string ParseXamlColor(string color)
    {
        if (color.StartsWith("#"))
        {
            // Remove transparancy value
            color = "#" + color.Substring(3);
        }
        return color;
    }

    private string ParseXamlThickness(string thickness)
    {
        string[] values = thickness.Split(',');

        for (int i = 0; i < values.Length; i++)
        {
            if (double.TryParse(values[i], out double value))
            {
                values[i] = Math.Ceiling(value).ToString();
            }
            else
            {
                values[i] = "1";
            }
        }

        switch (values.Length)
        {
            case 1:
                return thickness;
            case 2:
                return values[1] + " " + values[0];
            case 4:
                return values[1] + " " + values[2] + " " + values[3] + " " + values[0];
            default:
                return values[0];
        }
    }

    /// <summary>
    /// Reads a content of current xaml element, converts it
    /// </summary>
    /// <param name="xamlReader">
    /// XmlTextReader which is expected to be at XmlNodeType.Element
    /// (opening element tag) position.
    /// </param>
    /// <param name="htmlWriter">
    /// May be null, in which case we are skipping the xaml element;
    /// witout producing any output to html.
    /// </param>
    /// <param name="inlineStyle">
    /// StringBuilder used for collecting css properties for inline STYLE attribute.
    /// </param>
    private void WriteElementContent(XmlTextReader xamlReader, XmlTextWriter htmlWriter, StringBuilder inlineStyle)
    {
        bool elementContentStarted = false;

        if (xamlReader.IsEmptyElement)
        {
            if (htmlWriter != null && !elementContentStarted && inlineStyle.Length > 0)
            {
                // Output STYLE attribute and clear inlineStyle buffer.
                htmlWriter.WriteAttributeString("STYLE", inlineStyle.ToString());
                inlineStyle.Remove(0, inlineStyle.Length);
            }
            elementContentStarted = true;
        }
        else
        {
            while (ReadNextToken(xamlReader) && xamlReader.NodeType != XmlNodeType.EndElement)
            {
                switch (xamlReader.NodeType)
                {
                    case XmlNodeType.Element:
                        if (xamlReader.Name.Contains("."))
                        {
                            AddComplexProperty(xamlReader, inlineStyle);
                        }
                        else
                        {
                            if (htmlWriter != null && !elementContentStarted && inlineStyle.Length > 0)
                            {
                                // Output STYLE attribute and clear inlineStyle buffer.
                                htmlWriter.WriteAttributeString("STYLE", inlineStyle.ToString());
                                inlineStyle.Remove(0, inlineStyle.Length);
                            }
                            elementContentStarted = true;
                            WriteElement(xamlReader, htmlWriter, inlineStyle);
                        }
                        Debug.Assert(xamlReader.NodeType == XmlNodeType.EndElement || xamlReader.NodeType == XmlNodeType.Element && xamlReader.IsEmptyElement);
                        break;
                    case XmlNodeType.Comment:
                        if (htmlWriter != null)
                        {
                            if (!elementContentStarted && inlineStyle.Length > 0)
                            {
                                htmlWriter.WriteAttributeString("STYLE", inlineStyle.ToString());
                            }
                            htmlWriter.WriteComment(xamlReader.Value);
                        }
                        elementContentStarted = true;
                        break;
                    case XmlNodeType.CDATA:
                    case XmlNodeType.Text:
                    case XmlNodeType.SignificantWhitespace:
                        if (htmlWriter != null)
                        {
                            if (!elementContentStarted && inlineStyle.Length > 0)
                            {
                                htmlWriter.WriteAttributeString("STYLE", inlineStyle.ToString());
                            }
                            htmlWriter.WriteString(xamlReader.Value);
                        }
                        elementContentStarted = true;
                        break;
                }
            }
        }
    }

    /// <summary>
    /// Conberts an element notation of complex property into
    /// </summary>
    /// <param name="xamlReader">
    /// On entry this XmlTextReader must be on Element start tag;
    /// on exit - on EndElement tag.
    /// </param>
    /// <param name="inlineStyle">
    /// StringBuilder containing a value for STYLE attribute.
    /// </param>
    private void AddComplexProperty(XmlTextReader xamlReader, StringBuilder inlineStyle)
    {
        if (inlineStyle != null && xamlReader.Name.EndsWith(".TextDecorations"))
        {
            inlineStyle.Append("text-decoration:underline;");
        }

        // Skip the element representing the complex property
        WriteElementContent(xamlReader, /*htmlWriter:*/null, /*inlineStyle:*/null);
    }

    /// <summary>
    /// Converts a xaml element into an appropriate html element.
    /// </summary>
    /// <param name="xamlReader">
    /// On entry this XmlTextReader must be on Element start tag;
    /// on exit - on EndElement tag.
    /// </param>
    /// <param name="htmlWriter">
    /// May be null, in which case we are skipping xaml content
    /// without producing any html output
    /// </param>
    /// <param name="inlineStyle">
    /// StringBuilder used for collecting css properties for inline STYLE attributes on every level.
    /// </param>
    private void WriteElement(XmlTextReader xamlReader, XmlTextWriter htmlWriter, StringBuilder inlineStyle)
    {
        if (htmlWriter == null)
        {
            // Skipping mode; recurse into the xaml element without any output
            WriteElementContent(xamlReader, /*htmlWriter:*/null, null);
        }
        else
        {
            string htmlElementName;
            switch (xamlReader.Name)
            {
                case "Run" :
                case "Span":
                case "InlineUIContainer":
                    htmlElementName = "SPAN";
                    break;
                case "Bold":
                    htmlElementName = "B";
                    break;
                case "Italic" :
                    htmlElementName = "I";
                    break;
                case "Paragraph" :
                    htmlElementName = "P";
                    break;
                case "BlockUIContainer":
                case "Section":
                    htmlElementName = "DIV";
                    break;
                case "Table":
                    htmlElementName = "TABLE";
                    break;
                case "TableColumn":
                    htmlElementName = "COL";
                    break;
                case "TableRowGroup" :
                    htmlElementName = "TBODY";
                    break;
                case "TableRow" :
                    htmlElementName = "TR";
                    break;
                case "TableCell" :
                    htmlElementName = "TD";
                    break;
                case "List" :
                    string marker = xamlReader.GetAttribute("MarkerStyle");
                    if (marker == null || marker == "None" || marker == "Disc" || marker == "Circle" || marker == "Square" || marker == "Box")
                    {
                        htmlElementName = "UL";
                    }
                    else
                    {
                        htmlElementName = "OL";
                    }
                    break;
                case "ListItem" :
                    htmlElementName = "LI";
                    break;
                case "Hyperlink":
                    htmlElementName = "A";
                    break;
                default :
                    htmlElementName = null; // Ignore the element
                    break;
            }

            if (htmlWriter != null && htmlElementName != null)
            {
                htmlWriter.WriteStartElement(htmlElementName);

                WriteFormattingProperties(xamlReader, htmlWriter, inlineStyle);

                WriteElementContent(xamlReader, htmlWriter, inlineStyle);

                htmlWriter.WriteEndElement();
            }
            else
            {
                // Skip this unrecognized xaml element
                WriteElementContent(xamlReader, /*htmlWriter:*/null, null);
            }
        }
    }

    // Reader advance helpers
    // ----------------------

    /// <summary>
    /// Reads several items from xamlReader skipping all non-significant stuff.
    /// </summary>
    /// <param name="xamlReader">
    /// XmlTextReader from tokens are being read.
    /// </param>
    /// <returns>
    /// True if new token is available; false if end of stream reached.
    /// </returns>
    private bool ReadNextToken(XmlReader xamlReader)
    {
        while (xamlReader.Read())
        {
            switch (xamlReader.NodeType)
            {
                case XmlNodeType.Element: 
                case XmlNodeType.EndElement:
                case XmlNodeType.None:
                case XmlNodeType.CDATA:
                case XmlNodeType.Text:
                case XmlNodeType.SignificantWhitespace:
                    return true;

                case XmlNodeType.Whitespace:
                    if (xamlReader.XmlSpace == XmlSpace.Preserve)
                    {
                        return true;
                    }
                    // ignore insignificant whitespace
                    break;

                case XmlNodeType.EndEntity:
                case XmlNodeType.EntityReference:
                    //  Implement entity reading
                    //xamlReader.ResolveEntity();
                    //xamlReader.Read();
                    //ReadChildNodes( parent, parentBaseUri, xamlReader, positionInfo);
                    break; // for now we ignore entities as insignificant stuff

                case XmlNodeType.Comment:
                    return true;
                case XmlNodeType.ProcessingInstruction:
                case XmlNodeType.DocumentType:
                case XmlNodeType.XmlDeclaration:
                default:
                    // Ignorable stuff
                    break;
            }
        }
        return false;
    }

    #endregion Private Methods
}

}

该 dll 由 Windows 服务使用,并且 ConvertRtfToHtml 方法被调用多次。

这是windbg信息:

    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

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

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.

!dumpheap -stat 命令显示只有 2 Mo 是空闲的:

00e6a430      865      2382762      Free

这是性能数据:

enter image description here I don't know what to do to resolve this exception. I try to add GC.Collect() to force GC without any effect.

VM 有 8 Go 物理内存,而在另一个具有 4 Go 的 VM 上,不会发生异常。我不知道如何解决这个异常。

感谢您的帮助


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

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

这是正确的——这有力地表明垃圾收集本身并没有真正的帮助。即使它可以释放 4 MB,您也几乎一无所获。

(但是:稍后会详细介绍)

!dumpheap -stat命令显示只有 2 Mo 空闲

虽然这个说法并没有错,但它也不完整。

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

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

考虑到这些知识,你需要问

为什么操作系统不能为 .NET 提供更多内存?

原因可能是:因为它已经放弃了所有记忆。在 32 位进程中,这是 2 GB、3 GB 或 4 GB,具体取决于配置和设置(主要是 Large Address Aware)。这并不多,尤其是它不能作为连续的块使用。在许多情况下,您只有 700 MB。

操作系统在哪里分配了内存?对于您的情况中的 COM 对象(因为我们有一个 COM 异常,但这可能会产生误导)。这些 COM 对象似乎是本机的(否则它们会分配托管内存)。那么查看 .NET 内存并没有什么帮助。

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

如果这不是原因,则可能您的 RTF 太大并且不适合最大的可用内存区域。

我曾经编过一个解决 OOM 异常的图表 https://stackoverflow.com/questions/26142607/how-to-use-windbg-to-track-down-net-out-of-memory-exceptions/26150591#26150591它告诉您从哪里开始。

With !address -summary你从操作系统的角度看一下。

你可能有一个小<unknown>值,因为 .NET 使用量很小。

If Heap具有很大的值,内存通过 Windows 堆管理器(例如 C++)消失,并且存在本机泄漏(可能是由于 COM 对象未释放而引起)。

您还可以查看“按大小划分的最大区域”部分,您将在其中找到以下值:Free。这是某人通过单个请求可以获得的最大价值。也许它不足以适合您的数据。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Windbg 调试 .NET OutOfMemoryException 的相关文章

  • 秒表有最长运行时间吗?

    多久可以Stopwatch在 NET 中运行 如果达到该限制 它会回绕到负数还是从 0 重新开始 Stopwatch Elapsed返回一个TimeSpan From MSDN https learn microsoft com en us
  • .NET 中是否有内置函数可以对密码进行哈希处理?

    我看到这个问题加密 散列数据库中的纯文本密码 https stackoverflow com questions 287517 encrypting hashing plain text passwords in database 我知道我
  • Asp.NET WebApi 中类似文件名称的路由

    是否可以在 ASP NET Web API 路由配置中添加一条路由 以允许处理看起来有点像文件名的 URL 我尝试添加以下条目WebApiConfig Register 但这不起作用 使用 URIapi foo 0de7ebfa 3a55
  • 嵌套接口:将 IDictionary> 转换为 IDictionary>?

    我认为投射一个相当简单IDictionary
  • 类模板参数推导 - clang 和 gcc 不同

    下面的代码使用 gcc 编译 但不使用 clang 编译 https godbolt org z ttqGuL template
  • BitTorrent 追踪器宣布问题

    我花了一点业余时间编写 BitTorrent 客户端 主要是出于好奇 但部分是出于提高我的 C 技能的愿望 我一直在使用理论维基 http wiki theory org BitTorrentSpecification作为我的向导 我已经建
  • HTTPWebResponse 响应字符串被截断

    应用程序正在与 REST 服务通信 Fiddler 显示作为 Apps 响应传入的完整良好 XML 响应 该应用程序位于法属波利尼西亚 在新西兰也有一个相同的副本 因此主要嫌疑人似乎在编码 但我们已经检查过 但空手而归 查看流读取器的输出字
  • OleDbDataAdapter 未填充所有行

    嘿 我正在使用 DataAdapter 读取 Excel 文件并用该数据填充数据表 这是我的查询和连接字符串 private string Query SELECT FROM Sheet1 private string ConnectStr
  • 将多个表映射到实体框架中的单个实体类

    我正在开发一个旧数据库 该数据库有 2 个具有 1 1 关系的表 目前 我为每个定义的表定义了一种类型 1Test 1Result 我想将这些特定的表合并到一个类中 当前的类型如下所示 public class Result public
  • 重载<<的返回值

    include
  • WCF 中 SOAP 消息的数字签名

    我在 4 0 中有一个 WCF 服务 我需要向 SOAP 响应添加数字签名 我不太确定实际上应该如何完成 我相信响应应该类似于下面的链接中显示的内容 https spaces internet2 edu display ISWG Signe
  • SolrNet连接说明

    为什么 SolrNet 连接的容器保持静态 这是一个非常大的错误 因为当我们在应用程序中向应用程序发送异步请求时 SolrNet 会表现异常 在 SolrNet 中如何避免这个问题 class P static void M string
  • IEnumerable 与 IReadOnlyList

    选择有什么区别IEnumerable
  • 如何在整个 ASP .NET MVC 应用程序中需要授权

    我创建的应用程序中 除了启用登录的操作之外的每个操作都应该超出未登录用户的限制 我应该添加 Authorize 每个班级标题前的注释 像这儿 namespace WebApplication2 Controllers Authorize p
  • 如何查看网络连接状态是否发生变化?

    我正在编写一个应用程序 用于检查计算机是否连接到某个特定网络 并为我们的用户带来一些魔力 该应用程序将在后台运行并执行检查是否用户请求 托盘中的菜单 我还希望应用程序能够自动检查用户是否从有线更改为无线 或者断开连接并连接到新网络 并执行魔
  • WPF/C# 将自定义对象列表数据绑定到列表框?

    我在将自定义对象列表的数据绑定到ListBox in WPF 这是自定义对象 public class FileItem public string Name get set public string Path get set 这是列表
  • cmake 将标头包含到每个源文件中

    其实我有一个简单的问题 但找不到答案 也许你可以给我指一个副本 所以 问题是 是否可以告诉 cmake 指示编译器在每个源文件的开头自动包含一些头文件 这样就不需要放置 include foo h 了 谢谢 CMake 没有针对此特定用例的
  • 是否可以在 .NET Core 中将 gRPC 与 HTTP/1.1 结合使用?

    我有两个网络服务 gRPC 客户端和 gRPC 服务器 服务器是用 NET Core编写的 然而 客户端是托管在 IIS 8 5 上的 NET Framework 4 7 2 Web 应用程序 所以它只支持HTTP 1 1 https le
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现
  • 如何防止用户控件表单在 C# 中处理键盘输入(箭头键)

    我的用户控件包含其他可以选择的控件 我想实现使用箭头键导航子控件的方法 问题是家长控制拦截箭头键并使用它来滚动其视图什么是我想避免的事情 我想自己解决控制内容的导航问题 我如何控制由箭头键引起的标准行为 提前致谢 MTH 这通常是通过重写

随机推荐

  • 如何在 MacOS X 上以编程方式打开控制台窗口

    我想知道 是否可以在 MacOS X 上以编程方式打开控制台窗口并将 IO 重定向到它 类似于AllocConsole GetStdHandle Windows 上的 API 我打算在 xxx app 应用程序中使用它 该应用程序默认情况下
  • gdb在检查内存时如何同时显示hex和ascii?

    使用 x 100c 时 输出显示 ascii 和十进制 0x111111 40 40 gdb如何同时显示ascii和hex like 0x111111 0x28 C 0x28 C 这种格式更好 0x111111 0x28 0x28 CC 您
  • WooCommerce 可变产品通知问题 - 请选择产品选项

    我正在建立一个电子商务网站 我在使用 WooCommerce 时遇到一些问题可变产品 添加到购物车 按钮适用于简单产品 但不适用于可变产品 它给出了一个 Please choose product options notice 我到处寻找并
  • 如何在.NET中为SmtpClient对象设置用户名和密码?

    我看到不同版本的构造函数 一种使用 web config 中的信息 一种指定主机 一种指定主机和端口 但是如何将用户名和密码设置为与 web config 不同的内容呢 我们遇到的问题是我们的内部 smtp 被一些高安全性客户端阻止 并且我
  • 电子标题栏“无拖动”和“拖动”不起作用

    我有一个 topleft红色标题栏包含多个 选项卡 按钮 应填充所有可用空间except a topright蓝色块 可以通过单击并拖动来移动 Electron 主窗口 topleft的红色背景 感谢 webkit app region d
  • 如何在集群外部访问/公开 kubernetes-dashboard 服务?

    我有以下服务 ubuntu master kubectl get services all namespaces NAMESPACE NAME CLUSTER IP EXTERNAL IP PORT S AGE default kubern
  • 堆上数组的初始化

    如何手动初始化堆上数组中的值 如果数组是局部变量 在堆栈中 则可以以非常优雅且简单的方式完成 如下所示 int myArray 3 1 2 3 不幸的是 下面的代码 int myArray new int 3 myArray 1 2 3 编
  • 如何注入模拟程序集以与 Moq 一起使用

    我的控制器中有一个方法 它将属性数据从当前执行的程序集返回到分部视图中 在这个例子中 我只是拉动标题 但我需要用它做更多的事情 控制器 var title var asm Assembly GetExecutingAssembly var
  • jQuery - 通过文本描述设置选择控件的选定值

    我有一个选择控件 在 JavaScript 变量中我有一个文本字符串 使用 jQuery 我想将选择控件的选定元素设置为具有我拥有的文本描述的项目 而不是我没有的值 我知道按值设置它非常简单 例如 my select val myVal 但
  • 获取那些有子子 ul 的 li

    如何获得那些li有孩子的ul 我想将 CSS 设置为那些li 我无法设置班级 因为li是动态打印的 当我如下设置 CSS 时 它设置了所有父级li来加 ul width 200px position relative ul li posit
  • 贝塞尔曲线和画布

    如何在画布上绘制贝塞尔曲线 我只有起点和终点 我想从起点到终点画一条线 我怎样才能做到这一点 您可以使用Path quadTo or Path cubicTo 为了那个原因 示例可以在 SDK 示例 FingerPaint 中找到 在你的情
  • backbone.js 解析 1 个元素(Id)

    对于骨干模型上的 id 来说 它只是id并且全部小写 如果我在服务器上的Id被调用怎么办UserId 在主干的解析方法中 我该如何更改UserId to id并对所有其他属性使用相同的名称 For eg window User Backbo
  • JTable 的页脚

    JTable 不支持显示包含每列聚合数据的页脚 受到建议解决方案的启发Oracle Suns 错误数据库 https bugs java com bugdatabase view bug bug id 4242646看起来很有希望 我从用滚
  • Python + 正则表达式:如何在Python中提取两个下划线之间的值?

    我正在尝试提取两个下划线之间的值 为此我写了这段代码 patient ids for file in files print file patient id re findall file patient ids append patien
  • componentWillReceiveProps 与 getDerivedStateFromProps

    componentWillReceiveProps 和 getDerivedStateFromProps 到底是什么对我来说是个微妙的问题 因为 我在使用 getDerivedStateFromProps 时遇到了一个问题 Componen
  • python 请求和 cx_freeze

    我试图冻结一个依赖于请求的 python 应用程序 但出现以下错误 Traceback most recent call last File c Python33 lib site packages requests packages ur
  • 找不到 SPSite 名称空间

    我无法找到名称空间SPSite 到目前为止我已经导入了这些 using System using System Collections Generic using System Linq using System Text using Sy
  • Solr 创建核心时出错:在架构中找不到 fieldType [x]

    我正在尝试让 Solr 核心与我自己的一起运行schema xml 但是Solr 版本5 2 1 一直抱怨丢失fieldType甚至不在我的元素中fields定义 org apache solr common SolrException f
  • 我的股票市场计划可以使用什么数据源? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想为 Linux 和 Windows 制作一个免费的开源 C 应用程序 它将创建实时股票市场图表 即
  • 使用 Windbg 调试 .NET OutOfMemoryException

    我需要帮助调试 net dll 中的 OutOfMemoryException 该 dll 将 rtf 文本转换为原始文本或 html 这是转换代码 http matthewmanela com blog converting rtf to