2010-04-26 2 views
12

ОК, вот сделка. Есть некоторые люди, которые вкладывают свои жизни в руки сборщика мусора .NET, а некоторые просто не доверяют ему.Эффективность сборщика мусора .NET.

Я являюсь одним из тех, кто частично доверяет ему, если он не критичен с точки зрения производительности (я знаю, что знаю ... производительность критическая + .net не предпочтительная комбинация), и в этом случае я предпочитаю вручную распоряжаться своим объектов и ресурсов.

Что я спрашиваю, есть ли какие-либо факты относительно того, насколько эффективны или неэффективны по производительности сборщики мусора?

Пожалуйста, не делитесь личными мнениями или вероятными предположениями на основе опыта, я хочу непредвзятые факты. Я также не хочу обсуждать pro/con, потому что он не будет отвечать на вопрос.

Благодаря

Edit: Чтобы уточнить, я в основном говорю: Независимо от того, какое приложение мы пишем, ресурс критически или не может мы просто забыть обо всем, и пусть GC справиться с этим, или мы не можем ?

Я пытаюсь получить ответ на самом деле, что GC делает и не делает, и где он может потерпеть неудачу, когда управление ручной памятью будет успешным, если бы были такие сценарии. Есть ли ОГРАНИЧЕНИЯ? Я не знаю, как я мог бы объяснить свой вопрос дальше.

У меня нет никаких проблем с любым приложением, это теоретический вопрос.

+6

определить эффективный. не зная, как вы хотите измерить его эффективность, трудно ответить на это. –

+0

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

+0

Если вы ищете непредвзятые факты, почему бы вам не настроить некоторые тесты самостоятельно? Пройдите через некоторое создание и ручное уничтожение, а затем снова запустите ту же программу, не избавившись от чего-либо, и пусть GC заберет ее? Если вы хотите, чтобы цифры и анекдотические данные были не в порядке, настройте тесты, чтобы получить номера самостоятельно. – SqlRyan

ответ

9

Достаточно эффективен для большинства приложений. Но вам не нужно жить в страхе перед GC. В действительно горячих системах, требования к низкой задержке, вы должны программировать таким образом, чтобы полностью избежать этого. Я предлагаю вам взглянуть на этот Rapid Addition White Paper:

Хотя GC выполняется довольно быстро, это займет время, чтобы выполнить, и, таким образом, сбор мусора в вашем непрерывном режиме может ввести как нежелательную задержку и изменение латентность в тех приложениях, которые очень чувствительны к задержке, . В качестве иллюстрации, если вы обработки 100000 сообщений в секунду, и каждый сообщения использует небольшую временную 2 строку символов, около 8 байт (это функции от строки кодирования и реализации объекта String) выделяется для каждого сообщения. Таким образом, вы создаете почти 1 МБ мусора в секунду. Для системы, которая может обеспечить постоянную работу в течение 16-часового периода, это означает, что вам нужно будет очистить 16 часов x 60 минут x 60 секунд x 1 МБ Память приблизительно 56 ГБ памяти. Лучшее, что вы можете ожидать от сборщика мусора, что он будет очистить это полностью либо поколение 0 или 1 коллекции и вызывают джиттера, худшее, что вызовет поколение 2 мусора коллекцию ассоциированная больший латентный шип.

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

+0

Спасибо за тонну за эту информацию, очень ценю это. –

+0

Это было интересное чтение и ответы на многие мои вопросы, еще раз спасибо. –

1

Любой алгоритм GC будет способствовать определенной активности (т. Е. Оптимизации). Вам нужно будет протестировать GC против вашего шаблона использования, чтобы узнать, насколько он эффективен для вас. Даже если кто-то еще изучил специфическое поведение GC-GC и произвел «факты» и «цифры», ваши результаты могут быть совершенно разными.

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

+0

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

2

Вам не о чем беспокоиться.

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

И вы вряд ли найдете такие кромки. Это действительно потрясающе. Если вы использовали только кучевые распределители в типичных реализациях C и C++, .NET GC является совершенно другим животным. Я был так поражен этим I wrote this blog post to try and get the point across.

2

Вы не можете всегда забыть о распределении памяти, независимо от того, используете ли вы GC или нет. Какая хорошая реализация GC вы покупаете, так это то, что большую часть времени вы можете позволить себе не думать о распределении памяти. Однако нет конечного распределителя памяти. Для чего-то важного, вы должны знать, как управляется память, и это подразумевает знание того, как все делается внутренне. Это справедливо для GC и для распределения кучи вручную.

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

GC в текущих реализациях .NET: не в режиме реального времени; они эвристически эффективны и быстры. Обратите внимание, что то же самое можно сказать о ручном распределении с malloc() в C (или new на C++), поэтому, если вы находитесь в режиме реального времени, вам уже нужно использовать что-то особенное. Если вы этого не сделаете, я не хочу, чтобы вы проектировали встроенную электронику для автомобилей и самолетов, которые я использую!

5

Я могу рассказать вам о некоторых проблемах, которые у меня возникли с сборщиком мусора .NET.

Если вы используете приложение, использующее GC сервера (например, приложение ASP.NET), то ваша задержка будет действительно ужасной с паузами около секунды, когда ни один из ваших потоков не сможет добиться какого-либо прогресса на все. Это связано с тем, что GC-сервер .NET 4 является GC-стопом. По-видимому, .NET 4.5 представит первый в мире Microsoft-совместимый сервер GC.

Я как-то написал код инструментария для измерения задержек в параллельной системе с использованием встроенных коллекций, таких как ConcurrentBag, и в 32-разрядной памяти из-за массивной фрагментации кучи, и заканчивая нехваткой памяти, поскольку .NET GC не дефрагментирует большие объекты , Мне пришлось заменить массивы данных на основе массивов чисто функциональными структурами данных, которые разбросаны на миллионы крошечных фрагментов, чтобы избежать того, чтобы что-то на кучи больших объектов (LOH) вызывало фрагментацию.

Я нашел ошибки в GC как this one, что заставляет GC течь память до тех пор, пока вся системная память не будет исчерпана, после чего куча очищается в одном огромном цикле GC, который останавливает не только все ваши потоки, но даже другие процессы (потому что система пошла на своп) в течение нескольких минут!

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

Тем не менее, .NET GC, как правило, очень хорош, и при его использовании можно получить хорошие результаты. Например, я недавно написал отказоустойчивый сервер, который в среднем достигает 114 мкс с задержкой от двери до двери, при 95% латентности ниже 0,5 мс. Это впечатляюще близко к современному (см. here и here), учитывая, что я написал всю платформу в F # самостоятельно всего за несколько месяцев. Сеть действительно способствовала большей задержке, чем .NET GC.

+0

Это интересное чтение, спасибо! Я также прочитаю ссылки, которые вы опубликовали :) –

+1

Я могу подтвердить, что 'SustainedLowLatency' действительно просто отключает GC. Это было потрясение после того, как я получил «OutOfMemoryException», но в целом он оказался работоспособным, так как я почти не нуждался в латентности, когда мне это нужно, но мог терпеть паузы каждые несколько минут. Затем я переключился на «Concurrent» и очистил GC, прежде чем отключать его. – codekaizen

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