Использование памяти для сериализации блоков байтов с помощью Protobuf-net

В нашем приложении у нас есть некоторые структуры данных, которые, помимо прочего, содержат сокращенный список байтов (в настоящее время представлен какList<byte[]>). Мы разбиваем байты на части, потому что если мы позволим помещать байтовые массивы в кучу больших объектов, то со временем мы страдаем от фрагментации памяти.

Мы также начали использовать Protobuf-net для сериализации этих структур, используя нашу собственную сгенерированную DLL сериализации.

Однако мы заметили, что Protobuf-net создает очень большие буферы в памяти при сериализации. Просматривая исходный код, кажется, что, возможно, он не может очистить свой внутренний буфер до полногоList<byte[]>&nbsp;структура была написана, потому что она должна записать общую длину в начале буфера впоследствии.

Это, к сожалению, отменяет нашу работу с разбивкой байтов в первую очередь и в конечном итоге дает нам OutOfMemoryExceptions из-за фрагментации памяти (исключение возникает в тот момент, когда Protobuf-net пытается расширить буфер до более 84 КБ, что, очевидно, помещает его в LOH, и наше общее использование памяти процесса довольно низко).

Если мой анализ того, как работает Protobuf-net, верен, есть ли способ обойти эту проблему?

Update

Основываясь на ответе Марка, я попробовал вот что:

[ProtoContract]
[ProtoInclude(1, typeof(A), DataFormat = DataFormat.Group)]
public class ABase
{
}

[ProtoContract]
public class A : ABase
{
    [ProtoMember(1, DataFormat = DataFormat.Group)]
    public B B
    {
        get;
        set;
    }
}

[ProtoContract]
public class B
{
    [ProtoMember(1, DataFormat = DataFormat.Group)]
    public List<byte[]> Data
    {
        get;
        set;
    }
}

Затем сериализовать это:

var a = new A();
var b = new B();
a.B = b;
b.Data = new List<byte[]>
{
    Enumerable.Range(0, 1999).Select(v => (byte)v).ToArray(),
    Enumerable.Range(2000, 3999).Select(v => (byte)v).ToArray(),
};

var stream = new MemoryStream();
Serializer.Serialize(stream, a);

Однако, если я вставлю точку останова вProtoWriter.WriteBytes()&nbsp;куда это звонитDemandSpace()&nbsp;к нижней части метода и шаг вDemandSpace()Я вижу, что буфер не очищен, потому чтоwriter.flushLock&nbsp;равняется1.

Если я создам еще один базовый класс для ABase, как это:

[ProtoContract]
[ProtoInclude(1, typeof(ABase), DataFormat = DataFormat.Group)]
public class ABaseBase
{
}

[ProtoContract]
[ProtoInclude(1, typeof(A), DataFormat = DataFormat.Group)]
public class ABase : ABaseBase
{
}

затемwriter.flushLock&nbsp;равняется2&nbsp;вDemandSpace().

Я предполагаю, что есть очевидный шаг, который я пропустил здесь, чтобы сделать с производными типами?