побочные эффекты сборки мусора?

Это может быть в высшей степени закрытый вопрос, но я из тех, кто видит, что прилипает к стене. Несмотря на все преимущества управления памятью и временем жизни, предоставляемые средой выполнения со сборкой мусора, были ли какие-либо заметные случаи неопределенности программы, вызванной условиями гонки между приложением и его сборщиком мусора? Появился ли гештальт защитного программирования против подобных вещей? Конечно, программисты, привыкшие к RAII, должны извлечь уроки из присутствия GC.


person yacdmnky    schedule 14.03.2009    source источник


Ответы (4)


Проблема со сборкой мусора в том, что она управляет только ресурсами памяти. К сожалению, программистам приходится управлять множеством других типов ресурсов:

  • дескрипторы файлов и сокетов
  • подключения к базе данных
  • объекты синхронизации
  • ресурсы графического интерфейса

и это лишь некоторые из немногих. Чтобы успешно управлять ими, вам действительно нужны концепции, воплощенные в идиоме RAII.

person Community    schedule 14.03.2009

Я думаю, вы неправильно понимаете, как работает автоматический сбор мусора. Условия конкуренции между приложением и правильно реализованным сборщиком мусора невозможны даже в принципе. Сборщик мусора собирает только те объекты, к которым приложение не может получить доступ.

Поскольку только один из двух может когда-либо «владеть» данным объектом, условия гонки не могут возникнуть.

person MarkusQ    schedule 14.03.2009
comment
Они могут появиться, как только вы начнете рассматривать вопрос о завершении (и тем более, когда вы начнете делать такие вещи, как воскрешение объектов ...) - person Greg Beech; 14.03.2009
comment
В правильно реализованной системе сборки мусора у вас не должно быть возможности воскресить объект, имеющий право на сборку мусора, поскольку у вас не будет возможности ссылаться на него. Аналогичным образом, объект, проходящий финализацию, не подлежит сбору, поскольку вы все еще можете ссылаться на него. - person MarkusQ; 14.03.2009
comment
В CLR вы можете получить состояние гонки вокруг финализации. Прочтите это, в котором выделен один: blogs.msdn.com/cbrumme /archive/2003/04/19/51365.aspx - person Greg Beech; 16.03.2009
comment
Также см. Раздел о доступности здесь: blogs.msdn.com/ cbrumme / archive / 2004/02/20 / 77460.aspx - person Greg Beech; 16.03.2009
comment
@GregBeech Я сказал (и цитирую) В правильно реализованной системе GC; ваши ссылки (если они точны) просто демонстрируют, что CLR GC не реализован правильно. Им не нужно было делать это таким образом и по многим причинам, которых у них не должно было быть; говоря, что Microsoft сделала это, так что это должно быть правильно, просто не полетит. - person MarkusQ; 16.03.2009
comment
@MarkusQ: Есть ли у вас какие-либо ссылки, которыми можно подробнее рассказать о недостатках реализации .NET GC? - person yacdmnky; 17.03.2009
comment
@yacdmnky Все, что я знаю, это то, что Грег Бич связал выше. Если они верны (у меня нет прямого знания; утверждения, сделанные в связанных документах, могут быть совершенно неуместными, насколько я знаю), CLR GC очень плохо реализован, если он собирает как объекты мусора, которые все еще видны приложению - person MarkusQ; 17.03.2009
comment
@MarkusQ - Крис Брамм (автор статей) был главным архитектором CLR, так что вы можете считать их авторитетными. - person Greg Beech; 18.03.2009
comment
Также обратите внимание, что условия гонки возникают при работе с внешними ресурсами, которые не управляются (и не могут управляться) сборщиком мусора. Когда вы имеете дело только с управляемыми объектами, этих проблем нет. - person Greg Beech; 18.03.2009
comment
@MarkusQ: Завершение - это механизм, с помощью которого брошенные объекты, которые могут иметь другие объекты, выполняющие действия от их имени (например, резервирование области памяти, дескриптора файла и т. Д.), Могут уведомить эти другие объекты о прекращении этого действия. Когда сборщик мусора работает, он эффективно разделяет объекты на три категории: живые объекты, полностью мертвые объекты и брошенные объекты, которые запросили уведомление об оставлении. Хотя теоретически можно спроектировать систему, в которой объекты запрашивают уведомление об отказе, регистрируя другие несвязанные объекты (которые содержат информацию, необходимую для очистки) ... - person supercat; 03.02.2012
comment
@MarkusQ: ... и такой дизайн может устранить необходимость в категории брошенных объектов, объявив объекты очистки просто живыми, это вызовет проблемы, если два объекта прямо или косвенно будут зарегистрированы как отвечающие за очистку друг друга. Оба объекта всегда будут «живыми» - даже если единственной ссылкой на один из них была регистрация очистки другого - и ни один из них никогда не запустил бы свой код очистки. В .net GC оба объекта будут считаться заброшенными, но заброшенные объекты часто должны иметь возможность сохранять ссылки, которые они содержат, в живые объекты. - person supercat; 03.02.2012

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

Через шесть лет я могу сказать вам, что мои взгляды полностью изменились! Я могу припомнить только один раз за эти годы, когда у меня была утечка памяти из-за забытого .Dispose (). Сравните это с C ++, где вы производите утечку памяти каждый час кодирования ... ;-)

Недавно мне пришлось вернуться в мир C ++, и я совершенно ошеломлен! Я когда-то работал с этим и как? Мне кажется, что я как минимум в 10 раз более продуктивен в C #, чем в C ++. И вдобавок ко всему: распределитель памяти GC настолько невероятно быстр, что я до сих пор не могу в это поверить. Посмотрите на этот вопрос, из которого я должен был сделать вывод, что в моем конкретном случае версия .NET (C # или C ++ / CLI) выполнялась в 10 раз быстрее, чем версия C ++ MFC: Распределение строковой памяти C ++.

Я полностью обратился, но мне потребовалось много времени, чтобы полностью принять это.

person Dan Byström    schedule 14.03.2009
comment
Технически забвение Dispose () приводит к утечке ресурсов. Но благодаря GC это временное явление, финализаторы обеспечивают страховку, которой просто нет в неуправляемых языках. - person Henk Holterman; 14.03.2009
comment
В моем случае действительно БЫЛА утечка! Это было давно, пока я не понял, откуда он появился. Это было связано с тем, что элемент управления Tab заполнялся элементами UserControl, производными от TabPage. Это было очень интересно, и я попытался выделить его самостоятельно, просто чтобы продемонстрировать ... - person Dan Byström; 14.03.2009
comment
Утечка может произойти только тогда, когда класс не имеет финализатора (т. Е. Сломан) или когда какой-то неясный путь ссылки блокирует его. Это может легко случиться с событиями. - person Henk Holterman; 14.03.2009
comment
... или когда какой-то непонятный путь ссылки блокирует его .... Согласен! :-) А когда дело доходит до WinForms, все действительно непонятно, потому что он должен работать поверх Win32. - person Dan Byström; 14.03.2009

Когда я только начал программировать на C, мне нужно было быть очень методичным с моими malloc и realloc, и мне нужно было освободить все, что я не использовал. Это была простая задача с крошечными заданиями в колледже, такими как создание двоичного дерева. Простой...

Теперь, когда я начал разрабатывать приложение с графическим интерфейсом, написанным на всем языке C, мне приходилось больше думать и меньше программировать из-за того, что я должен обращать внимание на возможные утечки памяти. Это становилось проблемой. Я бы предпочел половину продукта, чем полусфу.

Я начал переходить на Java и C #. Мне нравилось, что все, что мне нужно было сделать, это разыменовать объект, и сборщик мусора подобрал бы его для меня. Я также заметил, что мои программы работали немного медленнее с использованием Java Swing (как и ожидалось), но это было управляемо.

По моим наблюдениям, процессоры становятся дешевле, а память - дешевле и быстрее, а программы с графическим интерфейсом потребляют больше памяти, чем раньше. Сборщик мусора действительно помогает получить продукт, который работает с минимальными проблемами с утечками памяти. Действительно удобно и может привести к плохим привычкам кодирования, однако их можно исправить.

РЕДАКТИРОВАТЬ:

Также см. это, это может помочь вам ответить на ваши вопросы. Хорошее чтение ИМО

person WarmWaffles    schedule 28.07.2010