C# OpenXML 内存泄漏

C# OpenXML memory leak

我注意到我的应用程序中存在内存泄漏并试图找出它。我不知道好的和免费的内存泄漏发现技术(有什么建议吗?)所以我让它变得简单 - 插入内存​​使用打印(有和没有 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不是那么好理解的。 "Using" 甚至单独的块 {} 也应该完全自行清理。他们没有。甚至更糟。这个例子被简化了。实际上,每次我在我的方法中执行这段代码时,内存都消失了。在这个例子中它是 90K。 100 个文件后是 9Mb。

通过所描述的方法,我还发现调用 GC 时我的应用程序中有几个地方会消耗并且不会 return 内存。每次调用 GC 的唯一结果是 4K 内存消失了。不幸的是我不能在简单的例子中重现它。

到目前为止我只找到了一个解决方案 - 当内存变得关键时我重新启动我的应用程序。不是很好的解决方案,但我找不到更好的解决方案。

好吧,如果我们坚持免费或者我们在生产环境中,我会使用 ADPlus 来创建内存转储并使用 WinDbg 来分析它。您可以 Google 周围有大量关于该主题的知识。

但更简单的方法是在您的应用程序处于 运行 时附加内存分析器。我使用的分析器是商业的,但在 Visual Studio 2013 中也有一个内置的内存分析器。转到 ANALYZE -> Performance and Diagnostics 和 select .NET 内存分配。