Вопрос о сборщике "мусора" в.NET (утечка памяти)

Да, из-за Глобальной блокировки интерпретатора (GIL) там может только выполнить один поток за один раз. Вот некоторые ссылки с некоторым пониманием об этом:

Из последней ссылки интересная кавычка:

Позволяют мне объяснить, что весь, который означает. Потоки, выполненные в той же виртуальной машине, и следовательно работавшие та же реальная машина. Процессы могут работать на той же реальной машине или в другой реальной машине. Если Вы проектируете свое приложение вокруг потоков, you’ve сделанный ничто для доступа к нескольким машинам. Так, можно масштабироваться к тому, как много ядер находятся на единственной машине (который будет довольно многими со временем), но действительно достигнуть веб-масштабов, you’ll должен решить несколько проблема с машиной так или иначе.

, Если Вы хотите использовать многоядерный, , pyprocessing определяет основанный на процессе API, чтобы сделать реальное распараллеливание. PEP также включает некоторые интересные сравнительные тесты.

8
задан Peter Mortensen 14 November 2009 в 23:23
поделиться

7 ответов

Да, сборщик мусора освобождает ваши объекты, когда они больше не используются.

То, что мы обычно называем утечкой памяти в .NET, больше похоже на:

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

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

Вот, я думаю, Я дам более сложный ответ, чтобы прояснить ситуацию.

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

Внутренне сборщик мусора управляет памятью в поколениях. В очень упрощенном виде существует несколько поколений долгоживущих, короткоживущих и крупных объектов. Сборщик мусора перемещает объект из одного поколения в другое каждый раз, когда он выполняет сборку, что происходит чаще для короткоживущего поколения, чем для долгоживущего. Он также перераспределяет объекты, чтобы получить максимально возможное непрерывное пространство, поэтому снова выполнение сбора - дорогостоящий процесс.

Если вы действительно хотите увидеть эффекты освобождения формы (когда вы выходите из области видимости и больше не имеете на нее ссылки), вы можете вызвать GC.Collect () . Делайте это только для тестирования, вызывать Collect крайне неразумно, за исключением очень немногих случаев, когда вы точно знаете, что делаете и какие последствия это будет иметь.

Еще немного объяснений о методе Dispose интерфейса IDispose.

Dispose - это не деструктор в обычном смысле C ++, это вообще не деструктор. Dispose - это способ детерминированного избавления от неуправляемых объектов . Пример. Предположим, вы вызываете внешнюю библиотеку COM, которая выделяет 1 ГБ памяти из-за того, что она делает. Если у вас нет Dispose, эта память будет сидеть там, трата места до тех пор, пока сборщик мусора не создаст коллекцию и не освободит неуправляемую память, вызвав деструктор фактического объекта. Поэтому, если вы хотите сразу же освободить память, вам нужно вызвать метод Dispose, но вас не «заставляют» это делать.

Если вы не используете интерфейс IDisposable, вам необходимо освободить неуправляемые ресурсы. в методе Finalize. Finalize автоматически вызывается из деструктора объекта, когда сборщик мусора пытается вернуть объект. Поэтому, если у вас есть правильный метод финализации, неуправляемая память будет освобождена в любом случае. Вызов Dispose только сделает его детерминированным.

Чтобы использовать интерфейс IDisposable, вам нужно освободить неуправляемые ресурсы в методе Finalize. Finalize автоматически вызывается из деструктора объекта, когда сборщик мусора пытается вернуть объект. Поэтому, если у вас есть правильный метод финализации, неуправляемая память будет освобождена в любом случае. Вызов Dispose только сделает его детерминированным.

Чтобы использовать интерфейс IDisposable, вам нужно освободить неуправляемые ресурсы в методе Finalize. Finalize автоматически вызывается из деструктора объекта, когда сборщик мусора пытается вернуть объект. Поэтому, если у вас есть правильный метод финализации, неуправляемая память будет освобождена в любом случае. Вызов Dispose только сделает его детерминированным.

12
ответ дан 5 December 2019 в 05:03
поделиться

Что заставляет вас сделать вывод об утечках памяти? При сборке мусора нет гарантии, что память будет освобождена немедленно , и, как правило, сборщик мусора не срабатывает до тех пор, пока память вашего процесса не достигнет некоторого порогового значения или пока доступная куча не будет исчерпана. (Точная эвристика сложна и не важна.) Поэтому тот факт, что память вашего процесса увеличивается, а не уменьшается, не обязательно означает наличие ошибки. Возможно, сборщик мусора еще не успел очистить ваш процесс.

Кроме того, вы уверены , что на ваши объекты нет ссылок? Возможно, у вас есть ссылки, о которых вы не знаете. Большинство утечек памяти в приложениях .NET происходит из-за того, что люди не

8
ответ дан 5 December 2019 в 05:03
поделиться

Я добавляю это как ответ, а не комментарий к вопросу, но это следует за вопросом, заданным OP в комментарии: с использованием оператора в MSDN. Интерфейс IDisposable в MSDN.

Вот суть проблемы: исчезло то, к чему вы привыкли в отношении деструкторов объектов. Все, что вам говорили о том, как правильно кодировать, кричит из вашего подсознания, говоря, что это не может быть правдой, а если это правда, то это неправильно и ужасно. Это совсем другое; Трудно вспомнить, как сильно я его сначала презирал (я был гордым разработчиком C ++).

Я лично обещаю вам: все будет хорошо!

Вот еще одна полезная вещь, которую стоит прочитать: Деструкторы и финализаторы в Visual C ++ .

4
ответ дан 5 December 2019 в 05:03
поделиться

Task Manager is a terrible way to examine your memory usage. If you want to study how the garbage collector works, install the CLR Profiler and use it to analyze your application. It will tell you exactly what the garbage collector is doing.

See How To: Use CLR Profiler.

7
ответ дан 5 December 2019 в 05:03
поделиться

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

3
ответ дан 5 December 2019 в 05:03
поделиться

Если вы просто хотите выяснить, есть ли у вас утечка памяти, взгляните на perfmon , который поставляется с вашей копией Windows:

В частности счетчик памяти .NET CLR байт во всех кучах , если это число постоянно растет, у вас утечка.

Вы можете копнуть глубже, сравнив размер кучи Gen 2 с размером кучи больших объектов. Если первое неуклонно растет, происходит утечка больших объемов данных.

Убедившись в наличии утечки, вы можете подключиться с помощью windbg и использовать расширения sos , чтобы определить, что именно происходит.

Если вы можете позволить себе потратить несколько долларов, обратите внимание на .NET Memory Profiler .

1
ответ дан 5 December 2019 в 05:03
поделиться

Есть бесплатные инструменты, которые можно посмотреть управляемая куча в .Net, используя расширения SOSEX для WinDBG и SOS , можно запустить программу, приостановить ее, а затем посмотреть, какие объекты существуют в стеке и (что более важно) какие другие объекты содержат ссылки на них (корни), которые будут препятствовать их сбору сборщиком мусора.

0
ответ дан 5 December 2019 в 05:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: