C# OpenXML内存泄漏问题

4
我注意到我的应用程序存在内存泄漏,并试图找出原因。我不知道有什么好的和免费的内存泄漏发现技术(有建议吗?),所以我简单地插入了内存使用打印(带和不带GC),然后深入挖掘最大的泄漏点。 我已经修复了可修复的部分,但有些无法修复,因为它们在包内。像这个非常简化的例子。
using System;
using System.Threading;
using DocumentFormat.OpenXml.Packaging;

namespace WorkTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("0) " + System.GC.GetTotalMemory(true).ToString("000,000,000", Thread.CurrentThread.CurrentCulture));
            Console.WriteLine("Start");
            Console.WriteLine("1) " + System.GC.GetTotalMemory(true).ToString("000,000,000", Thread.CurrentThread.CurrentCulture));

            using (WordprocessingDocument wordPackage = WordprocessingDocument.Open(@"c:\tmp\a.docx", true))
            {
              // This is Open XML Format SDK 2.5 - v4.0.30319
              // It does nothing within this particular block/example 
            }
            Console.WriteLine("2) " + System.GC.GetTotalMemory(true).ToString("000,000,000", Thread.CurrentThread.CurrentCulture));
            Console.WriteLine("End");
            Console.WriteLine("3) " + System.GC.GetTotalMemory(true).ToString("000,000,000", Thread.CurrentThread.CurrentCulture));
        }
    }
}

通常它会生成类似以下的内容:
0) 000,215,984
Start
1) 000,218,528
2) 000,325,472
End
3) 000,325,472

开始处理小的泄漏 - 步骤0-1是简单的输出。它不会占用太多内存,只有3K,但它仍然存在。步骤2-3相同,但它不会占用任何内存。 好的。我同意。一些IO包可能需要一些内存。这不好,但可以理解。
第二个问题 - 步骤1-2并不是那么容易理解。"使用"甚至独立的块{}应该完全清除自己。但它们没有。更糟糕的是,这个例子是简化的。实际上,每次在我的方法中执行此代码时,内存都会消失。在这个例子中,它是90K。在100个文档后,它是9Mb。
通过所描述的方法,我还发现了我的应用程序中的几个地方,当调用GC时,它会消耗内存并且不会返回内存。每次调用GC时,唯一的结果就是4K的内存消失。不幸的是,我无法在简单的示例中重现它。
到目前为止,我只找到了一个解决方案 - 当内存变得紧张时,我重新启动我的应用程序。这不是一个好的解决方案,但我找不到更好的解决方案。

试试这个链接 --> https://dev59.com/xXVC5IYBdhLWcg3w9GLM 我已经将它加入书签了,因为里面有一些非常有用的建议、链接和答案。 - waltmagic
我确实很感激有关内存泄漏对抗工具的帮助。但是当我在OpenXML中发现内存泄漏时,我该怎么办呢?这就是我发布这个例子的原因。我不知道如何对抗这种内存泄漏——难道不使用OpenXML?还是Windows? - Alex
我经常使用OpenXML,通常不会遇到内存问题。如果您阅读我发布的链接中的所有答案,您将找到许多博客文章和文章,介绍了解决问题的策略,而不仅仅是工具。 - waltmagic
我喜欢你的链接,也收藏了它。谢谢。 - Alex
1个回答

2
如果我们坚持使用免费工具或者在生产环境中,我会使用ADPlus创建内存转储,然后使用WinDbg进行分析。你可以在谷歌上搜索相关知识。
但更简单的方法是在应用程序运行时附加内存分析器。我使用的分析器是商业软件,但Visual Studio 2013中也有一个内置的内存分析器。进入ANALYZE->Performance and Diagnostics并选择.NET内存分配。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接