| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > .NET для новичков > А бывают ли утечки памяти? |
| Автор: Dims 11.11.2008, 05:09 |
| А бывают ли в Си# утечки памяти? Зачем нужен IDisposable? Часто ли он встречается? Если забыть Dispose, что будет? Как проконтролировать? |
| Автор: Partizan 11.11.2008, 09:59 | ||
| Конечно утечки бывают...бажный код -> висячие ссылки на объекты -> сборщик мусора не убивает их...в итоге получаем утечку... А насчёт IDisposable в MSDN всё предельно ясно написано...
Вопроса "Часто ли он встречается" я вообще не понял...вы о чём? Ответ на последние два вопроса лежит в приведённой выше цитате из MSDN |
| Автор: PashaPash 11.11.2008, 11:32 |
| Dims, еще можно добавить невыгружаемые генерируемые сборки и утечки дескрипторов. Частота встречания зависит от опыта. Например, у класса XmlSerializer 9 конструкторов, из них 7 сильно текут. Это описано в документации, но кто ее читает... |
| Автор: Dims 11.11.2008, 12:49 |
Это как? Можно поподробнее? Я не врубаюсь. Является ли это обязательным или это просто желательно? Тоже, если можно, поподробнее |
| Автор: Partizan 11.11.2008, 13:06 | ||||
Dims,
Обязательным это не является. Использовать IDisposable необходимо, если ваш класс занимает unmanaged-ресурсы и при удалении объекта их необходимо освобождать. GС при удалении объекта IDisposable обязательно вызовет Dispose.
Ну, допустим у вас есть класс-коллекция с собственной имплементацией добавления / удаления объектов... Допустим реализация удаления немного бажная....и иногда объект из коллекции не удаляется, а новые объекты всё так же добавляются... В результате объекты, которые по сути нигде не используются остаются торчать в коллекции и GC их на тот свет никак не хочет забирать... В итоге получаем о-го-гошное отжирание памяти... Пример немного надуман, но общий смысл проблемы с "висящими ссылками", думаю, передаёт. |
| Автор: PashaPash 11.11.2008, 14:19 | ||
LeakSample1 каждый раз создает динамическую сборку и не выгружает ее. И к тому же тормозит. Причины и последствия описаны в документации. LeakSample2 закрепляет объект в памяти перед передачей неуправляемому коду. И забывает открепить - не обязательно намеренно, может быть просто из-за исключения в неуправляемом коде. В результате в памяти образуется кусок, который GC не может освободить, и который ему приходится обходить при сборке мусора. Но чаще всего утечки - это просто висящие ссылки, часто неявные. Например, нестатические обработчики событий и callback-и. Но такие случаи можно отловить профайлером. |
| Автор: Partizan 12.11.2008, 09:24 | ||||||
Вы и сами не знаете, что объекты не удаляете...вы думаете, что удаляете, а из-за багов в коде, объекты не удаляются фактически, потому-что ссылки остаются висеть...Я же сказал, что пример немного надуман, но демонстрирует проблему висящих ссылок. Есть более удачный пример...
http://www.google.ru/search?hl=ru&newwindow=1&client=firefox-a&rls=org.mozilla%3Aru%3Aofficial&hs=cgo&q=.net+profiler&btnG=%D0%9F%D0%BE%D0%B8%D1%81%D0%BA&lr=&aq=f&oq= |
| Автор: PashaPash 12.11.2008, 10:39 |
memprofiler.com и стандартный sos. Весь бонус сборщика мусора в том, что он сам знает какие объекты нужны. Возьми рихтера, там подробно расписан процесс. |
| Автор: mr.DUDA 12.11.2008, 12:15 |
| Dims, про память в дотнет на основе сборки мусора и поколений отлично у Джеффри Рихтера в книге расписано. |
| Автор: nerezus 12.11.2008, 16:26 |
| Утечек в pure MSIL не быввает. Бывают ошибки, когда уже ненужные переменные "как будто нужны и используются", но это уже ошибки проектирования. |
| Автор: PashaPash 12.11.2008, 17:11 |
| nerezus, тогда и в unmanaged коде утечек памяти не бывает. Просто неосвобожденная память "как будто нужна и используется" - обычная ошибка проектирования. |
| Автор: nerezus 12.11.2008, 17:40 |
| PashaPash, мы можем присвоить ссылке другое значение в unmanaged коде, но объект в оперативке то остается. Это утечка. |
| Автор: Partizan 12.11.2008, 17:56 | ||
nerezus,
Переменная t ссылается на новый объект, старый объект остался... |
| Автор: PashaPash 12.11.2008, 20:13 |
| nerezus, в примере LeakSample2 выше ссылки на управляемый объект objectToPin уже нет, но он остается в оперативке и GC его обходит стороной. Есть только отметка "этот кусок памяти занят" - ну так она и в unmanaged коде есть. Это тоже утечка. В чистом MSIL. Просто в managed понятие утечки шире - это когда объект живет дольше, чем должен по представлению разработчика. |
| Автор: mr.DUDA 13.11.2008, 11:23 | ||
Старый поток вместе со старым объектом Thread подгребётся на следующей же сборке мусора |
| Автор: elbjarn 13.11.2008, 12:08 |
| банальность: вызовите метод Close() в обработчике OnLoad у формы - получите утечку |
| Автор: Partizan 13.11.2008, 12:45 |
| mr.DUDA, как старый поток подгребётся, если он ещё выполняется? |