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

Разделение кучи при использовании байтовых массивов

У меня есть приложение С# 4.0 (один производитель/один потребитель), который передает огромное количество данных в куски. Хотя никакого нового выделения памяти у меня нет, через некоторое время закончится память.

Я профилировал память, используя профайлер памяти Redgate, и там есть много свободной памяти. Он говорит, что свободная память не может использоваться из-за фрагментации.

Я использую блокирующую коллекцию в качестве массива буфера и байта как члены:

BlockingCollection<byte[]> segments = new BlockingCollection<byte[]>(8);
// producer:
segments.Add(buffer);
// consumer:
byte[] buffer = _segments.Take();

Как избежать фрагментации управляемой памяти?

4b9b3361

Ответ 1

Вероятно, вы столкнулись с проблемой кучи больших объектов - объекты размером более 85 000 байт помещаются в кучу большого объекта, которая не уплотняется, что может привести к странным ситуациям с памятью. Хотя, по-видимому, производительность в .NET 4 была улучшена, она далека от совершенства. Решение состоит в том, чтобы в основном использовать собственный пул буферов, который содержит несколько статически распределенных блоков памяти и повторное использование этих файлов.
В этом вопросе есть целая куча вопросов.

Обновление. Microsoft предоставляет диспетчер буфера как часть стека WCF. Существует также один в кодепроекте.

Ответ 2

Как долго ваш массив byte []? Они попадают в маленький предмет или кучу больших объектов? Если вы испытываете фрагментацию памяти, я бы сказал, что они попадают в LOH.

Поэтому вы должны повторно использовать одни и те же байт-массивы (использовать пул) или использовать более мелкие куски. LOH никогда не уплотняется, поэтому он может стать довольно фрагментированным. К сожалению, этого не происходит. (Не зная этого ограничения и избегая его)