Как сериализовать большие объекты в .NET? (Исключения OutOfMemory) - PullRequest
2 голосов
/ 02 апреля 2009

Я использую сериализацию для функции «сохранить» в моем приложении. Но когда данные слишком велики (15+ МБ), я начинаю получать исключения OutOfMemory.

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

Мой код основан на этом, почти то же самое:

http://www.codeproject.com/KB/vb/TreeViewDataAccess.aspx

Редактировать:

  1. Я не использую пользовательскую сериализацию, все это делается с помощью атрибутов [Serialization]. Исключая некоторые поля.

  2. Я сериализую так много объектов и пользовательских классов. Включает словарь, структуры и кучу других вещей.

  3. Я сериализую его в файл.

  4. Я использую XmlSerializer

P.S. У меня 4 ГБ физической памяти.

Решение

Благодаря ответам моя проблема была связана с XmlSerializer, и я от нее избавился. Двоичная сериализация прекрасно работает с данными, которые у меня есть.

Ответы [ 7 ]

3 голосов
/ 18 августа 2009

У меня была точно такая же проблема. Причина в том, что .NET сериализация не масштабируется.

Я решил проблему с помощью превосходного открытия Саймона Хьюитта. исходная библиотека, см. Оптимизация сериализации в .NET - часть 2 .

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

2 голосов
/ 02 апреля 2009

На самом деле, XmlSerializer игнорирует атрибуты SerializableAttribute. Они используются только классами форматирования (BinaryFormatter, SoapFormatter).

Я бы не стал сериализовать, используя XmlSerializer, и особенно не сочетание XmlSerializer и BinaryFormatter.

Я бы просто попытался сериализовать все, используя BinaryFormatter.

1 голос
/ 02 апреля 2009

15 МБ не должны давать вам OOM.

Если данные имеют древовидную структуру (а не полный график), вы можете использовать сериализатор как protobuf-net ; кроме того, что он использует очень эффективный (как по скорости, так и по памяти) двоичный формат «буферов протокола» Google, он не требует отслеживания ссылок (необходим для графиков) - это означает, что он должен беспокоиться о данных только один раз (дважды, если он получить буфер).

Однако для этого требуется разметка, отличная от ваших классов (или, по крайней мере, "согласие"), и она не будет обрабатывать полные графики. Но она есть и бесплатная ...

0 голосов
/ 07 ноября 2016

Вы можете загрузить JSON.NET Библиотека, которая работает в моем проекте с сериализацией и десериализацией данных более 100 МБ.

Для сериализации вы можете работать как

Если у вас есть Object, используйте TextWriter

using (TextWriter textWriter = File.CreateText("LocalJsonFile.json"))
{
    var serializer = new JsonSerializer();
    serializer.Serialize(textWriter , yourObject);
}

Если у вас есть строка, используйте StringWriter

  StringBuilder sb = new StringBuilder();
  StringWriter sw = new StringWriter(sb);

  using(JsonWriter textWriter = new JsonTextWriter(sw))
  {
     var serializer = new JsonSerializer();
     serializer.Serialize(textWriter, yourObject);
  }

Это может сработать для вас.

0 голосов
/ 09 апреля 2009

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

Также выполняем сжатие, используя gzip или 7-Zip , прежде чем двоичное форматирование больших объектов фактически переместит размер выше 16 МБ в нечто вроде 32 МБ.

0 голосов
/ 02 апреля 2009

Может быть, вы можете дать нам немного больше информации о том, как производится сериализация. Вы используете пользовательскую сериализацию? Или вы просто используете встроенный атрибут [Serialization]?

Я думаю, что для вас хороший способ справиться с этим - попытаться выполнить свою собственную логику сериализации и сериализовать только то, что вам нужно, она не может быть до 4 ГБ, в любом случае, это также зависит от объема памяти вашего приложения. назначен.

0 голосов
/ 02 апреля 2009

Вы можете написать свои собственные процедуры сериализации и посмотреть, сможете ли вы получить какие-либо преимущества в производительности, адаптируя процесс сериализации вручную. Для получения дополнительной информации см. Страницу MSDN в Пользовательской сериализации .

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