2015-05-13 1 views
4

Я заметил утечку памяти в своем приложении и попытался ее найти. Я не знаю, какая хорошая и свободная память просачивает методы обнаружения (любые предложения?), Поэтому я сделал это просто - вставлял распечатки использования памяти (с GC и без нее), а затем копал глубже, где была большая утечка. Fixable я исправил, но некоторые не могу, потому что они внутри пакетов. Как это очень упрощенно одинC# OpenXML утечка памяти

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 тот же, но ничего не есть. ОК. Согласен. Некоторым пакетам ввода-вывода может понадобиться некоторая память. Нехорошо, но понятно.

Второй этап - шаг 1-2 не такой понятный. «Использование» и даже отдельный блок {} должны полностью очищаться после себя. И они этого не делают. Еще хуже. Этот пример упрощен. В действительности каждый раз, когда я выполняю этот код в моей памяти методов, уходит. В этом примере это 90K. После 100 документов это 9Mb.

С описанной методологией я также обнаружил несколько мест в своем приложении при вызове GC и не возвращает память. Каждый раз, когда GC называется единственным результатом, что память 4K исчезла. К сожалению, я не могу воспроизвести его в простом примере.

До сих пор я нашел только одно решение - когда память стала критической, я перезапустил приложение. Нехорошее решение, но я не могу найти лучшего.

+0

Попробуйте эту ссылку здесь -> http://stackoverflow.com/questions/134086/what-strategies-and-tools-are-useful-for-finding-memory-leaks-in-net У меня есть закладки, потому что есть некоторые очень полезные предложения/ссылки/ответы там – waltmagic

+0

Я действительно ценю помощь с инструментами борьбы с утечкой памяти. Я делаю! Но что я могу сделать, когда обнаруживаю утечку памяти в OpenXML? Вот почему я опубликовал этот пример. Я не знаю, как бороться с этой утечкой памяти - не используйте OpenXML? Или Windows? – Alex

+0

Я использую OpenXML все время и обычно не имею проблем с памятью. Если вы прочитаете все ответы по ссылке, которую я разместил, вы найдете множество сообщений в блогах и статей для стратегий устранения неполадок, а не только инструментов. – waltmagic

ответ

1

Ну, если мы придерживаемся свободной или мы находимся в производственной среде, я бы использовал ADPlus для создания дампа памяти и WinDbg для его анализа. Вы можете использовать Google, там есть много знаний по этому вопросу.

Но проще всего было бы подключить профилировщик памяти во время работы вашего приложения. Профайлеры, которые я использую, являются коммерческими, но есть также встроенный профилировщик памяти в Visual Studio 2013. Перейдите в ANALYZE -> Производительность и диагностика и выберите распределение памяти .NET.