C #: GC будет собирать, если ему нужна память, или он выдаст исключение из памяти? - PullRequest
5 голосов
/ 18 мая 2011

У меня в коде есть цикл, который генерирует множество массивов byte [] (около 1–2 МБ каждый), заполняет их данными и затем отбрасывает ссылку. Таким образом, хотя ссылка проводится только для короткое время я вижу, как растет частный рабочий набор.

Теперь, если я попытаюсь выделить большой массив (~ 400 МБ) после цикла, могу ли я получить исключение нехватки памяти? Или это заставит GC собирать временные данные?

Спасибо!

Ответы [ 3 ]

2 голосов
/ 18 мая 2011

Генерация множества массивов по 1-2 МБ - плохая идея.Даже если вы избежите нехватки памяти, производительность действительно страдает.Распределение многих недолговечных объектов в куче больших объектов - это схема распределения, с которой текущий GC плохо справляется.

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

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

1 голос
/ 18 мая 2011

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

0 голосов
/ 18 мая 2011

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

...