Строки кажутся слишком длинными - PullRequest
0 голосов
/ 03 февраля 2011

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

Проблема, с которой я сталкиваюсь, заключается в том, что сборщик мусора, похоже, не заботится о сериализованных строках.3500 файлов записей выполняются до OutOfMemoryException до того, как они завершатся.Действительно, что-то подозрительно.

Когда я вынимаю сериализацию из микса и просто пропускаю пустую строку, потребление памяти остается ожидаемым, поэтому я исключил возможность того, что мои промежуточные объекты (междуФайл и XML) являются проблемой здесь.Кажется, они собраны, как и ожидалось.

Кто-нибудь может помочь?Как мне убедиться, что эти строки утилизированы правильно?

Обновление: Пример кода

// myObj.Serialize invokes an XmlSerializer instance to handle its work    
string serialized = myObj.Serialize();
myXmlWriter.WriteRaw(serialized);

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

Обновление 2: метод сериализации

public virtual string Serialize()
{
      System.IO.StreamReader streamReader = null;
      System.IO.MemoryStream memoryStream = null;

      using (memoryStream = new MemoryStream())
      {
          memoryStream = new System.IO.MemoryStream();
          Serializer.Serialize(memoryStream, this);

          memoryStream.Seek(0, System.IO.SeekOrigin.Begin);
          using (streamReader = new System.IO.StreamReader(memoryStream))
          {
              return streamReader.ReadToEnd();
          }
      }
}

Ответы [ 4 ]

2 голосов
/ 03 февраля 2011

Вы должны убедиться, что на них нигде нет ссылок.Перед генерацией OutOfMemoryException запускается GC.Если он не восстанавливает эту память, это означает, что что-то все еще держится за нее.Как уже говорили другие, если вы разместите некоторый код, мы сможем помочь.В противном случае вы можете использовать профилировщик или WinDbg / SOS, чтобы выяснить, что удерживает ваши строки.

1 голос
/ 03 февраля 2011

Очень любопытно. Я добавил следующий денди после каждой записи сериализованной записи в XmlWriter:

if (GC.GetTotalMemory(false) > 104857600)
{
     GC.WaitForPendingFinalizers();
}

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

0 голосов
/ 03 февраля 2011

Похоже, ваш метод может быть очищен до:

public virtual string Serialize()
{
    StringBuilder sb = new StringBuilder();
    using (StringWriter writer = new StringWriter(sb))
    {
        this.serializer.Serialize(writer, this);
    }

    return sb.ToString();
}

Вы создаете дополнительный MemoryStream без причины.

Но если вы пишетестрока в файл, тогда почему бы вам просто не отправить FileStream методу Serialize()?

0 голосов
/ 03 февраля 2011

У вас есть пример вашего кода - как вы создаете эти строки? Вы взламываете неуправляемый код где-либо (это означает, что вам придется убирать за собой).

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

...