4

I had noticed memory leak in my application and tried to find it out. I don't know good and free memory leaking discovering techniques (any suggestions?) so I made it simple - inserted memory usage prints (with and without GC) and then dig deeper where biggest leak was. Fixable I had fixed but some I can not because they are inside packages. Like this very simplified one

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));
        }
    }
}

usually it produces something like

0) 000,215,984
Start
1) 000,218,528
2) 000,325,472
End
3) 000,325,472

To start with small leak - step 0-1 is simple output. It doesn't eat a lot. Only 3K but it still something. Step 2-3 is the same but it doesn't eat anything. OK. I agree. Some IO packages may need some memory. Not good but understandable.

Second one - step 1-2 is not such understandable. "Using" and even separate block {} should totally clean after themselves. And they don't. Even worse. This example is simplified. In reality every time when I execute this code within my methods memory is gone. In this one example it is 90K. After 100 documents it is 9Mb.

With described methodology I also found few places in my app when invoking GC consumes and doesn't return memory. Every time GC is called the only result that 4K memory is gone. Unfortunately I cannot reproduce it in simple example.

So far I had found only one solution - when memory became critical I restart my application. Not good solution but I can't find better one.

Alex
  • 4,457
  • 2
  • 20
  • 59
  • Try this link here --> http://stackoverflow.com/questions/134086/what-strategies-and-tools-are-useful-for-finding-memory-leaks-in-net I have it bookmarked because there are some very useful suggestions/links/answers there – waltmagic May 13 '15 at 20:12
  • I really do appreciate help with memory leak fighting tools. I do! But what can I do when I find memory leak in OpenXML? That was the reason why I posted this example. I don't know how to fight this memory leak - don't use OpenXML? Or Windows? – Alex May 13 '15 at 22:02
  • I use OpenXML all the time and don't usually have memory issues. If you read through all the answers in the link I posted you will find numerous blog posts and articles for troubleshooting strategies, not just tools. – waltmagic May 13 '15 at 22:08
  • I like your link and bookmarked it too. Thanks. – Alex May 14 '15 at 00:57

1 Answers1

2

Well, if we're sticking with free or we're in a production environment, I would use ADPlus to create a memory dump and WinDbg to analyze it. You could Google around there's plenty of knowledge out there on the subject.

But the easier way would be to attach a memory profiler while your application is running. The profilers I use are commercial, but there's also a built-in memory profiler in Visual Studio 2013. Go to ANALYZE -> Performance and Diagnostics and select .NET memory allocation.

Zer0
  • 7,191
  • 1
  • 20
  • 34