2017-02-01 8 views
0

У меня есть класс, где на основе определенного события I initialize диалоговое окно с новой формой и initialize. В этом диалоговом окне на основе формы есть другие элементы управления внутри него.Ошибка утечки памяти в приложении формы C#

Когда закрыт dialog, я очищаю и удаляю все элементы управления, которые создаются в форме. К сожалению, кажется, что что-то не удаляется или остается в памяти даже после удаления.

Форма насос

class someClass 
{ 
    System.Timers.Timer someTimer; 
    public void CallToChildThread(Object stateInfo) 
    { 
     // check some event 
     // if true, fire event 
    } 
    someClass() 
    { 
      someTimer= new System.Threading.Timer(CallToChildThread, 
            autoEvent, 1000, 250); 
      _show += new EventHandler(eventCheck); 
    } 
    void eventCheck() 
    { 
     formClass formClassObject = new formClass(); //create form 
     formClassObject.someFunction(); // has some other function and does a showDialog on self 
     formClassObject.Dispose(); 
     formClassObject = null; 
    } 
} 

Внутри объекта formClass, при получении события FormClosed, я распоряжаюсь от всех элементов управления и контроля в рамках управления внутри объекта, но есть еще заметная утечка памяти.

Форма класс

public partial class formClass 
{ 
    //Initialize a bunch of managed resources to null 
    someOtherForm form2; 
    someOtherForm form3; 
    //connect some events on child forms to buttons on this form object 
    this.form2.cancelButtonClicked += someFunction; 
    this.form3.cancelButtonClicked += someFunction; 
    // Form closed Event 
    private void formClass_FormClosed(object sender, FormClosedEventArgs e) 
    { 
     //set form2 and form3 visibility to false 
     // clear AND dispose all controls of form2 
     // clear AND dispose all controls of form3 
     //set form2 and form3 to null 
     // clear AND dispose off all controls of formClass 
     // Dispose this (formClass) object 
    } 
} 

Есть ли возможная проблема с тем, как я инициализирован объектами формы? Разве они не попадают?

+3

Почему вы думаете, что есть утечка памяти? Обратите внимание, что сбор мусора решает сам _when_ фактически освободить память. Это происходит не обязательно сразу, но в конечном итоге может быть сделано, когда gc замечает, что памяти больше не хватает для выполнения следующего запроса на распределение. btw: если вы разместите форму, она сама выберет все свои элементы управления, не нужно делать это вручную. –

+0

Какое поведение приводит вас к мысли, что есть утечка памяти? – tonythewest

+1

Попробуйте утилизировать таймер, а также объект формы? –

ответ

1

Пожалуйста, смотрите здесь: Memory Leaks in Winforms application

Попытка удалить обработчик события (_show) перед утилизацией, чтобы действительно иметь ребенка формирует память утилизированы.

+0

Позвольте мне спросить, что может быть глупым вопросом ... Как событие, _show, влияет на объект formClass? Это просто событие в someClass (которое не является формой), которое сигнализируется, когда условие выполняется в таймере. Кроме того, если я избавляюсь от этого события, _show, то какой будет сигнал таймера позже? – user1173240

+0

@ user1173240 Я не уверен, поскольку я не вижу ваш метод 'form.someFunction' внутри вашего ответа, но для правильного определения проблемы мне нужно будет увидеть весь ваш объект' formClass'. Устранение или закрытие формы только избавляет от элементов пользовательского интерфейса. Если у вас есть переменные, объекты, обработчики событий и т. Д. В вашем 'formClass', вам нужно иметь событие FormClosed для вызова формы' .Dispose() 'на всех объектах. Это мое лучшее предположение, не видя всего кода для себя. –

+0

Я добавил код, который описывает, что я делаю в formClass formClosed event. – user1173240

0

Вы не удаляете обработчик событий, и это может быть источником утечки. Возможно, вы должны сделать someClassодноразовый и удалить обработчик в методе Dispose.

Как вы подтверждаете, что есть утечка? Сборщик мусора может работать с задержкой, давая ощущение, что память не собирается. Вы можете явно вызвать гб после каждого удаления формы и посмотреть, что происходит:

formClassObject.Dispose(); 

GC.Collect(); 
GC.WaitForPendingFinalizers(); 
GC.Collect(); 
GC.WaitForPendingFinalizers(); 

Некоторые другие советы:

Формы, которые вы создаете может генерировать исключения и не утилизировать должным образом. Поскольку вы создаете модальные диалоговые окна (вызов ShowDialog) вы должны использовать используя шаблон:

using (formClass formClassObject = new formClass()) 
{ 
    formClassObject.someFunction(); 
} 

Вы можете устранить утечку с помощью .NET профайлеров.

Посмотреть этот пост альтернативы:

What Are Some Good .NET Profilers?

+0

думаю, что есть утечка, потому что каждый раз, когда я запускаю событие, которое создает новую форму и инициализирует элементы управления, память заметно увеличивается. Отдельно счетчик объектов пользователя в управлении задачами для приложения увеличивается. Если я открываю 10 форм, объем памяти увеличивается довольно сильно, так что пользовательские объекты, но не спускаются, даже если я закрываю все формы, независимо от того, как долго я оставлю приложение запущенным. Пользовательские объекты подсчитывают немного, но остаются высокими. Я думал, что это может быть проблема с источником данных для пользовательского интерфейса, но все объекты и элементы управления управляются и должны уходить с закрытием формы. – user1173240

+0

Это имеет смысл. Возможно, вы можете решить проблему с помощью профилировщика .NET или постепенно ослабить свой класс форм, делая минимальные вещи (если это возможно). Обычно это источник данных, который неправильно настроен (как вы уже подозреваете), если обнаружена большая утечка памяти. – GeorgeT