2013-03-29 3 views
2

У меня есть серьезная утечка памяти на одном из моих исполняемых файлов C# (это консольное приложение). Объем памяти увеличивается и сверхурочно мне нужно перезапустить приложение, чтобы снизить использование памяти. Я использую FileSystemWatcher, а затем, когда файл доступен, перейдя к его преобразованию в utf-8 и пересылая его. А затем напишите на консоль, что файл обрабатывается в это время. Поэтому он записывает на консоль каждый раз, когда обрабатывает ее.Идентификация утечки памяти

Я использую профилировщик памяти Ants и довольно свежий, чтобы начать использовать его. Я не могу понять это. Когда я беру снимок памяти, он показывает мне:

namespace: System, Classname: byte [] --- Это увеличивается каждый раз, когда обрабатывает файл и отображает его на консоли (на 40 000 байт) и никогда не возвращается ,

Это правильно.

Update:

class Class1 
{ 
    private static FileSystemWatcher watcher = new FileSystemWatcher(); 

    public static void Main() 
    { 
     WatchFile(); 
     Console.ReadLine(); 
    } 

    private static void WatchFile() 
    { 
     watcher.Path = @"N:\"; 
     watcher.NotifyFilter = NotifyFilters.LastWrite; 
     watcher.Filter = "*.xml"; 
     watcher.Changed += new FileSystemEventHandler(convert); 
     watcher.Error += new ErrorEventHandler(WatcherError); 
     watcher.EnableRaisingEvents = true; 

     Console.WriteLine("Press \'q\' to quit."); 

     while (Console.Read() != 'q'); 
    } 

    public static string CrL = "\r\n"; 

    private static object lockObject = new object(); 

    private static void convert(object source, FileSystemEventArgs f) 
    { 
     string FileName; 
     FileName = f.FullPath; 

     string destinationFile = @"F:\test.xml"; 

     Thread.Sleep(2000); 
     if (!Monitor.TryEnter(lockObject)) 
     { 
      return; 
     } 
     try 
     { 
      watcher.EnableRaisingEvents = false; 
      Thread.Sleep(2000); 

      var doc = new XmlDocument(); 
      doc.Load(FileName); 

      XmlWriterSettings settings = new XmlWriterSettings { Encoding = Encoding.UTF8, Indent = true }; 

      using (var writer = XmlWriter.Create(destinationFile, settings)) 
      { 
       doc.Save(writer); 
      } 

      Console.WriteLine("File Copied" + " " + DateTime.Now.ToString("HH:mm:ss tt")); 
      Console.WriteLine("Press \'q\' to quit."); 
      Console.Write(CrL); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine("The process failed: {0}", e.ToString()); 
     } 
     finally 
     { 
      Monitor.Exit(lockObject); 
      watcher.EnableRaisingEvents = true; 
      GC.Collect(); 
      GC.WaitForPendingFinalizers(); 
      GC.Collect(); 
     } 
    } 

    private class Utf8StringWriter : StringWriter 
    { 
     public override Encoding Encoding { get { return Encoding.UTF8; } } 
    } 

    private static void WatcherError(object source, ErrorEventArgs e) 
    { 
     Exception watchException = e.GetException(); 
     watcher = new FileSystemWatcher(); 
     while (!watcher.EnableRaisingEvents) 
     { 
      try 
      { 
       WatchFile(); 
       Console.WriteLine("I'm Back!!"); 
      } 
      catch 
      { 
       Thread.Sleep(2000); 
      } 
     } 
    } 
} 
+1

Что вы спрашиваете? –

+1

Можете ли вы показать код своего файлового обозревателя? Трудно сказать, что происходит по описанию. – Tim

+0

Отредактировано для добавления кода – user726720

ответ

2

Похожий вопрос здесь - Memory leak while using Threads

Из того, что я понял из решения, писать в консоли и используя Thread.Sleep был вопрос.

Кроме того, может быть применимо (или нет) - http://support.microsoft.com/kb/2628838

Скачать Исправление (Надежность обновления 2 для Framework 4.0) файл с здесь- http://support.microsoft.com/kb/2600217

+0

Я не вижу, чтобы он создавал здесь какие-то новые темы. – jordanhill123

+0

Да, нет новых тем, но есть еще письмо для консоли. И я думаю, что проблема заключалась в использовании Threading и Thread.Sleep, а не в создании новых Threads (Answer Edited). По крайней мере, это мое понимание. – Arun

+0

Спасибо за ссылку для исправления .. Может быть, это может сработать, но я не могу загрузить это из ссылки. Возможно ли, вы можете указать мне, где я могу скачать это с – user726720

2

Попробуйте так:

var doc = new XmlDocument(); 
doc.Load(FileName); 

XmlWriterSettings settings = new XmlWriterSettings { Encoding = Encoding.UTF8, Indent = true }; 

using (var writer = XmlWriter.Create(destinationFile, settings)) 
{ 
    doc.Save(writer); 
} 
doc = null; 

Если вы не установите документ в нуль, то GC может увидеть его по-прежнему в качестве активной ссылки и не бесплатно память. У GC есть своя логика сбора мусора и принудительная сборка мусора не самая лучшая практика (Best Practice for Forcing Garbage Collection in C#).

Также я не считаю, что у вас есть утечка памяти; похоже, что GC не был запущен, чтобы освободить память. Что вы имеете в виду, когда говорите, что память продолжает расти? Какой уровень он достигает, когда вы чувствуете, что вам нужно вернуть его обратно?

EDIT

Смотрите эту ссылку для опций чтения файлов XML: Deciding on when to use XmlDocument vs XmlReader

При работе с очень большими файлами XML, можно получить XMLDocuments выделенного на большом объекте куче (лох), который может вызывают фрагментацию в LOH и приводят к исключениям OutOfMemory.

XMLReader может быть лучше для вас здесь.

+0

Спасибо за это. Да, я пробовал это. Это все равно. В муравьях он показывает мне, что частные байты (byte []) увеличиваются на 40 000 байт каждый раз, когда обрабатывает файл и отображает его на консоли. – user726720

+0

Тогда как вы запускаете GC, чтобы освободить память. 3 из этих приложений остались запущенными для разных папок. Для заполнения 1 гб памяти, которую я имею на машине, требуется 15 дней. Итак, приложениям требуется перезагрузка или компьютер нуждается в перезагрузке, чтобы обновить – user726720

+0

Заставляет ли приложение выдавать исключения из памяти или система заметно замедляется? Что вы используете в качестве триггера для перезагрузки ПК? – jordanhill123

 Смежные вопросы

  • Нет связанных вопросов^_^