Подтвердить что ты не робот

Эффективность сборщика мусора .NET

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

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

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

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

Спасибо

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

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

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

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

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

Ответ 3

Вам не нужно беспокоиться об этом.

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

И вы вряд ли найдете такие крайние случаи. Это действительно потрясающе. Если вы использовали только кучевые распределители в типичных реализациях C и С++,.NET GC является совершенно другим животным. Я был так поражен этим Я написал это сообщение в блоге, чтобы попытаться найти точку в.

Ответ 4

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

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

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

Ответ 5

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

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