Как сериализовать большие объекты в .NET?(Исключения из памяти)

StackOverflow https://stackoverflow.com/questions/709399

Вопрос

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

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

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

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

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

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

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

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

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

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

Решение

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

Это было полезно?

Решение

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

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

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

Другие советы

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

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

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

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

Я бы не стал сериализовать с помощью XmlSerializer, и особенно не стал бы использовать комбинацию XmlSerializer и BinaryFormatter.

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

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

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

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

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

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

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

Для сериализации вы можете работать следующим образом

Если у вас есть объект, используйте 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);
  }

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top