удалить очень большой объект в C # - PullRequest
3 голосов
/ 13 марта 2011

вертолёт. Я новичок в c #, и я получил большую картину с GC, удаляющим объекты, которые не могут быть достигнуты моим кодом. Проблема в том, что я работаю с некоторыми большими (7-40 МБ) объектами, хорошо, что они мне не нужны сразу, так есть ли какой-нибудь возможный способ удаления объекта? Я попробовал это:

- create big object X
- use big object X
  X = null; /*so I don't have any referance to it any more*/
  GC.Collect();
  GC.WaitForPendingFinalizers(); - create next big object ....`

Гарантирует ли это, что большой объект будет удален после выхода из GC.WaitForPendingFinalizers();?

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

спасибо!

Ответы [ 5 ]

16 голосов
/ 13 марта 2011

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

1 голос
/ 13 марта 2011

в значительной степени единственный способ получить a (единственное) большого объекта - это иметь очень большую строку или массив (возможно, инкапсулированный в длинном списке).В противном случае у вас просто большой граф мелких объектов (много).Маленькие объекты не проблема;если на него больше нет ссылок, GC в какой-то момент очистит его и сократит пространство (в зависимости от реализации GC).

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

Пока что "исправить" просто;не звоните в GC;и проверьте, что у вас нет пропущенной ссылки.

Другая проблема, однако, заключается в том, что у вас есть массивы / строки, которые достаточно велики, чтобы перейти в «кучу больших объектов» (LOH).LOH не уплотнен, поэтому вы можете столкнуться с проблемами фрагментации здесь.Одним из сомнительных способов решения этой проблемы является использование зубчатого массива, то есть 1000 массивов длиной 1000 (плюс дополнительный массив для их отслеживания) вместо одного массива длиной 1 000 000 - YMMV.

1 голос
/ 13 марта 2011

Не звоните GC.Collect вручную.Если вы не будете осторожны, вы продвигаете слишком много объектов в поколение 1, что сделает их более долговечными.

В .NET текущая реализация Microsoft разделяет большие объекты (я полагаю,> 84 КБ), и они получаютУправляется отдельно.Следовательно, ваш большой объект будет собирать мусор иначе, чем обычные объекты, на основе алгоритма сборщика мусора (который изменяется с версии .NET на версию .NET).

Проверьте эту ссылку на кучу больших объектов: http://msdn.microsoft.com/en-us/magazine/cc534993.aspx

1 голос
/ 13 марта 2011

Не говоря уже о ваших навыках грамматики, я бы сказал, что невозможно на 100% быть уверенным, что объект будет удален, когда вы этого захотите.
GC освобождает память по своему усмотрению, вызывая GC.Collect не освобождает каждый объект без ссылки немедленно.
Он удаляется, но не в этот момент.Звонить в GC.Collect без знания того, что он на самом деле делает, никогда не будет хорошей идеей!Оставьте это в покое, GC знает, что он делает.

0 голосов
/ 13 марта 2011

Только один вопрос: были ли у вас проблемы с вашим кодом?Не хватает памяти?

Это похоже на преждевременные оптимизации

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...