2010-10-21 3 views
8

Я пытаюсь уменьшить использование памяти приложением winForm.Просто открывать и закрывать диалог winform увеличит использование памяти

В приложении есть основная форма и форма настройки. Когда была нажата кнопка «Настройка», форма настройки будет отображаться как модальная форма, форма настройки загрузит данные app.config из файла конфигурации и прочитает их в памяти как Hashtable. После закрытия формы настройки он вызовет метод Dispose, присущий Windows.Forms.Form. Метод Dispose так же прост, как и для объектов Hashtables и app.config.

Показать SettingForm в modalform:

private void btnSettings_Click(object sender, EventArgs e) 
    { 
     frmConfig form = new frmConfig(); 
     form.StartPosition = FormStartPosition.CenterScreen; 
     //MessageBox.Show(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)); 
     form.ShowDialog(this); 
     form.Dispose(); 
    } 

Метод Dispose:

protected override void Dispose(bool disposing) 
    { 
     if (disposing && (components != null)) 
     { 
      components.Dispose(); 
      // Release managed resources 
      Logger.Verbose("Disposing SettingForm"); 
      mySetting = null; 
      testFtp = null; 
     } 
     base.Dispose(disposing); 
    } 

Примечание: mySetting является экземпляром класса со всеми данными App.config были нагрузки в Hashtable, и testFtp - это настраиваемый объект для функции ftp. Должен ли я реализовать метод Dispose для этого два класса и с использованием

mySetting.Dispose(); 
testFtp.Dispose(); 

вместо них установить нулевое значение, так как они сам себе/справиться с неуправляемыми ресурсами?

Но каждый раз нажимайте кнопку «Настройка» и закрывайте форму настройки, увеличивая частный байт на несколько сотен K. Утечка памяти? Как я могу избавиться от него?

+1

Это поможет, если вы разместите хотя бы часть своего кода, в частности код, в котором вы показываете форму, и ваш полный метод Dispose из формы настройки. – MusiGenesis

+0

Кроме того, простой вызов logging или debug.print или что-то еще внутри метода Dispose будет проверять, действительно ли он вызван или нет. – MusiGenesis

+1

Установка ссылки на 'null' не освобождает память. –

ответ

1

Как вы сказали в конце своего вопроса, я рекомендовал бы реализовать IDisposable на mySetting и testFtp. Вы должны лучше видеть очистку ресурсов, как только вы выполнили следующие действия:

protected override void Dispose(bool disposing) { 
    if (disposing && (components != null)) { 
     components.Dispose(); 

     // Release managed resources 
     Logger.Verbose("Disposing SettingForm"); 
     mySetting.Dispose(); 
     testFtp.Dispose(); 
    } 

    base.Dispose(disposing); 
} 

Малые изменения: на основе ответа NAYaN и в ответ он связывает с: Я бы настоятельно рекомендовать реализацию IDisposable. Используя Forms и исходя из криков класса Forms, «Проверьте необходимость внедрения IDisposable». Это не означает, что ваш код должен реализовывать его, просто убедитесь, что вам действительно нужно убедиться, что он вам не нужен. В формах обычно публикуется и подписывается множество событий. Формы также печально известны тем, что они становятся всепогодным ведром ресурсов, ИМО.

+0

Спасибо, я думаю, что управление памятью в .NET на самом деле не так просто исключить несколько очевидных вещей. Я в значительной степени сделал все необходимое (IDisposable полностью вниз, где это имеет смысл (неуправляемые ресурсы invlued) и два профайлера перекрестной проверки). Похоже, что использование памяти намного более стабильно. Но по-прежнему используйте больше. Я имею в виду, что если я так сильно забочусь о памяти, я должен рассмотреть возможность удаления всего содержимого GUI и подумать об использовании C++ или C: D –

1

Память не может быть освобождена из-за какой-либо другой части кода. Поскольку вы не представили много деталей, я буду считать, что все остальное оптимально.

Объекты, с которыми вы работаете, собираются сборщиком мусора (как вы знаете). Но они не могут быть освобождены из памяти, когда вы этого захотите. Объекты .NET лучше оставлять сборщику мусора.

По почему память не может быть получение освобождения you have the answers here.

Установка ссылок на объект нуль не имеет большого значения. С другой стороны, я лично записывал несколько раз, объекты возвращались живыми (и подталкивались к старым поколениям), потому что вы используете их при установке нулевого значения. Это еще одна форма вмешательства в GC, но ваш выбор.

Возможно, вам не нужно реализовывать IDisposable, но если вы работаете с потоками, то дескрипторы ОС, неуправляемые ресурсы, вам следует.

Edit:

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

+0

Согласно этой статье, я нашел, что это очень полезно для новичков, как я, кстати, http://www.dotnetfunda.com/articles/article625-best-practices-no-5--detecting-net-application-memory -leaks-.aspx Постоянно увеличивать использование памяти в байт-байте, указывая на утечку неуправляемых ресурсов, в этом случае я должен убедиться, что они правильно выпущены, а это значит, что мне нужно IDisposable полностью вниз, я думаю? –

+0

Это отличная статья, которую я пропустил. Спасибо за это! Хорошо, если вы «знаете», что это неуправляемая утечка памяти, затем найдите места, где неуправляемая память получает выделение. Вы можете реализовать интерфейс IDisposable и освободить неуправляемые элементы объекта. Но также убедитесь, что коды, объем которых ограничен функцией, также освобождают память. Они не могут быть освобождены в методе Dispose. Например: закрытие потока в функции - это можно обрабатывать только в этой функции! Всего наилучшего! – Nayan

0

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

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