Утилизация и управление ресурсами в C # - PullRequest
0 голосов
/ 16 сентября 2010

Я использую BackGroundWorker и ProgressBar.

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = sender as BackgroundWorker;

    e.Result = MyMethod((int)e.Argument, worker, e);

}

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage;
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    tStripStatus.Text = "operation Ended.";
    tStripStatus.ForeColor = Color.Green;
}

В MyMethod Я использую Dispose() метод для необходимых ресурсов.

  • Когда мое приложение запускается, оно использует ~ 10 000 К памяти.
  • Когда мое приложение работает, оно использует от ~ 40 000 до ~ 70 000 КБ памяти.
  • Когда операция завершена, оно использует ~ 30 000 К памяти.

    Как узнать, что использует память 30 000 k - 10 000 k = ~ 20 000 k?

Ответы [ 6 ]

2 голосов
/ 16 сентября 2010

Вызов Dispose() в .Net не сразу собирает память - он оставляет ее, пока он не занят чем-то другим.

По сути, он не собрал эти 20 МБ, потому что потраченная впустую память еще не замедляет его. На вашей машине, вероятно, нет свободного места, зачем останавливаться и приводить в порядок, когда еще достаточно места?

Позвоните GC.Collect(), чтобы заставить его, но учтите, что это обычно медленнее, чем оставлять .Net, чтобы делать свое дело. .Net неплохо собирает только тогда, когда это необходимо, если вы распорядитесь ресурсом. .

1 голос
/ 16 сентября 2010

Как я могу поймать, что использует 30 000 К - 10 000 К = ~ 20 000 К памяти?

Используя профилировщик памяти. Но учтите:

  • поиск простой метрики (Taskmanager) для «потребления памяти» близок к бессмысленному
  • у вас, вероятно, нет проблем
  • это не связано с Bgw

И для хорошей меры:

  • Ваш обработчик Completed не проверяет наличие ошибок. Может привести к неприятным ошибкам.
1 голос
/ 16 сентября 2010

Вы можете попробовать VMMap из Sysinternals .это бесплатный MS-инструмент, который позволяет анализировать использование памяти процессом.

Если вы не очень знакомы с профилированием приложения, попробуйте это отличное видео:

http://www.microsoftpdc.com/2009/CL11

В нем есть часть об анализе памяти.Как уже написано, не стоит слишком сильно рассчитывать на значения, предоставляемые taskmanager и ProcessInfo.Поскольку GC не работает сразу, есть большая вероятность, что освобождение еще не сделано из-за эффективности.

0 голосов
/ 16 сентября 2010

Вы можете использовать профилировщик памяти ANTS, чтобы посмотреть, что находится в памяти. Это отличный инструмент для поиска утечек памяти и т. Д. - загрузите пробную версию здесь: http://www.red -gate.com / products / ants_memory_profiler / index.htm

Возможно ли, что в MyMethod () вы, возможно, подключили событие от внешнего класса, которое не отсоединяется, когда вы закончите с методом?

Но, как упоминал Кит, объекты остаются в памяти до тех пор, пока не будет запущен сборщик мусора. Пока они правильно утилизируются, они будут освобождены при необходимости. Даже вызов GC.Collect () не гарантирует, что сборщик мусора запустится немедленно.

0 голосов
/ 16 сентября 2010

Если вы хотите знать, что занимает это место, вам придется использовать Memory Profiler, например ProfileSharp .

0 голосов
/ 16 сентября 2010

CLR отвечает за управление памятью, поэтому, если вы не используете внешние ресурсы из своего кода, память будет освобождена при запуске сборщика мусора.

...