2012-05-10 2 views
0

Я использую C#, но, вероятно, то же самое в VB.NET. Я C++ Я бы просто установил точку прерывания для деструктора объектов, чтобы знать, когда/если он был удален/свободен. Я понимаю, что в winforms базовый класс вызывает SupressFinalize, так что деструкторы формы никогда не вызываются, поэтому я думаю, что я не могу так поступать. Есть ли другой способ узнать, был ли объект собран мусором? Похоже на catch-22, потому что если бы вы были, вам, вероятно, понадобилась бы ссылка на проверку, но, удерживая эту ссылку, собранный мусор не раздавит ее.Как узнать, собрана ли форма формы winform?

Я читал это What strategies and tools are useful for finding memory leaks in .NET?, и я понимаю, что есть инструменты и/или фреймворки для обработки этой «большой картины», и я уверен, что через несколько недель я попробую несколько из этих методов. На данный момент у меня очень сильное чувство, что у меня может быть утечка, связанная с тем, что формы не удаляются, поэтому просто хочу проверить это одно (и я хочу знать только ради знания).

Я знаю, что могу смотреть Dispose, но я уверен, что Dispose можно назвать, но все равно в конечном итоге с объектом формы, все еще находящимся вокруг. Чтобы проверить эту теорию, я создал известную проблему, в которой я зарегистрировался для события обратного вызова в своей форме, а затем закрыл форму, не отменив ее. Конечно же, Dispose был вызван (и «распоряжение» было правдой), но позже, когда событие было уволено, оно все равно ударило мою точку останова внутри формы, которая предположительно была удалена.

+2

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

ответ

3

Есть на самом деле две проблемы:

Что касается вашего первоначального вопроса, вы можете использовать WeakReference контролировать наличие объекта, не затрагивая его жизни.

Ваш основной вопрос предполагает, что у вас есть непонимание того, что такое сборка мусора и как это работает. Точка сбора мусора заключается в том, что вам все равно, если объект был собран или нет. Вместо этого вам следует сосредоточиться на ссылках на объект, и если они были переназначены или сделаны недоступными из корневых ссылок. Не беспокойтесь о случае, беспокоитесь о ссылках на него.

+0

WeakReference.IsAlive будет делать то, что мне нужно, спасибо. Я понимаю GC и знаю, что есть инструменты, которые показывают мне каждую ссылку на объект, и в этом я должен сосредоточиться в долгосрочной перспективе. Пока я просто искал способ узнать, был ли собран один конкретный объект, это сделает это. – eselk

0

Вся концепция управляемого языка заключается в том, что вам не нужно заботиться, когда объект на самом деле собирает мусор. В GC необходимо много времени и усилий, чтобы убедиться, что он не собирает объекты, которых он не должен, чтобы он не оставил объекты, которые он должен собрать (когда он решает сделать проход над поколением, это в) и что все это сделано достаточно эффективно. Это означает, что если объект потребляет большое количество управляемых ресурсов, а также реализует IDisposable (например, DataTable или DataSet), он все еще потребляет лат памяти, и избавление от него не заставляет мусор собираться быстрее (хотя вы все равно должны избавиться от него, чтобы все управляемые ресурсы исчезли).

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

Утилизация не имеет ничего общего с сбором мусора или сбором объекта. Утилизация - это механизм для работы с управляемым объектом, который держится на unmangaed ресурсе (или другом объекте, который держится на unmangaed ресурсе). Утилизация объекта говорит ему прояснить этот неуправляемый ресурс, но он не имеет ничего общего с сборщиком мусора, освобождающим управляемые ресурсы этого объекта. Деструктор существует, так что вы не освобождаете управляемые ресурсы до освобождения неуправляемых ресурсов, но вполне приемлемо (и на самом деле должно всегда случиться), что неуправляемые ресурсы очищаются (через dispose) до освобождения управляемого ресурса.

Теперь все еще возможно, учитывая все это, для программы, имеющей утечку памяти, но есть несколько вопросов, которые вам действительно нужно задать себе в первую очередь. Насколько велика утечка? Это один, непрерывный со временем, каждый раз, когда мы выполняем функцию X и т. Д.? Что потребуется для того, чтобы программа потребляла столько памяти, чтобы быть разрушительной (либо закончилась нехватка памяти, что другие программы исчерпали память, и т. Д.), И может ли это произойти с обычным или законным использованием программы? Обычно вам не нужно начинать задавать эти типы вопросов до тех пор, пока не начнете получать исключения из памяти или не заметите, что у вас закончилась физическая память для программы, которая не должна. Если вы заметили эти проблемы, вы можете начать искать объекты, которые реализуют IDisposable, которые не располагаются, чтобы посмотреть, удерживаете ли вы ссылки на очень большие объекты (или коллекции объектов), которые вам больше не нужны, и т. Д.

Извините за стену с текстом.

+0

Это только для целей отладки/обучения, а не для производственного кода. Это часть производственного проекта, но этот код не останется. Просто используется как один из многих инструментов для проверки подлинности утечки памяти определенного типа, я хочу быть уверенным в том, чтобы избежать - потому что это будет " каждый раз, когда мы выполняем функцию X ", и может расти, если я случайно свяжу объект с ошибкой. – eselk

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