Как я могу отладить OutOfMemoryException без стека трассировки? - PullRequest
1 голос
/ 23 октября 2019

Когда я запускаю свое приложение .NET Core на сервере Linux, я получаю исключение OutOfMemoryException. Я совершенно не представляю, как я могу это отладить, потому что трассировка стека не предоставляется. Единственный вывод: «Необработанное исключение: OutOfMemoryException.»

В данный момент выбрасывается это исключение, остается достаточно места. Используется 200 ГБ ОЗУ и 300 ГБ свободно, поэтому я не думаю, что с памятью должны быть какие-либо проблемы.

В тот момент, когда это происходит, я пытаюсь сериализовать объект в protobuf. Окончательный файл должен быть около 1 ГБ. У меня никогда не было этой проблемы прежде, и модели сериализовались довольно хорошо.

Я был бы очень благодарен за любое понимание. Мне действительно нужно, чтобы это работало :( Я уже пытался вызвать это прямо перед сериализацией, потому что я думал, что проблема была с фрагментацией. После 10 часов вычислений я понял, что это не так.

_logger.LogDebug("LOH compaction start");
GCSettings.LargeObjectHeapCompactionMode = 
GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();
_logger.LogDebug("LOH compaction end");

Код, который яя выполняю, когда генерируется исключение, это:

        public static void Serialize<T>(this ProtobufSerializer protobufSerializer, string filePath, T serializationObject)
        {
            using (var fileStream = new FileStream(filePath, FileMode.Create))
            {
                protobufSerializer.Serialize(fileStream, serializationObject);
            }
        }

Ответы [ 2 ]

2 голосов
/ 23 октября 2019

Вам нужен очень систематический подход для выявления и разрешения OOM.

  1. Не думайте, что если у вас много свободной оперативной памяти, это все для вашего приложения.
  2. OOMsочень печально замаскировать себя, вы могли бы видеть, что трассировка стека указывает куда-то еще, и проблема на самом деле была бы в другом месте, в том смысле, что какой-то другой код протекает / потребляет большую память и помещает использование памяти на грани и где-то допустимый кодиначе попытка защитить некоторую ограниченную память подтолкнет ее к OOM.
  3. Используйте какой-нибудь профилировщик и определите область, где память увеличивается / протекает. (Похоже, вы определили это как код для сериализации больших данных.)
  4. Затем поработайте над этими областями и постарайтесь минимизировать использование памяти.
0 голосов
/ 23 октября 2019

Исключение OutOfMemory будет выдано только в том случае, если размер системного бита не превышает размер используемого вами объекта.

Исключение OutOfMemoryException имеет две основные причины: -

1.Выпытаются расширить объект StringBuilder за пределы длины, определенной его свойством StringBuilder.MaxCapacity.

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

...