Загрузка и обработка большого файла (120 МБ) в памяти выдает ошибку OOM, когда ОЗУ все еще доступно.C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Загрузка и обработка большого файла (120 МБ) в памяти выдает ошибку OOM, когда ОЗУ все еще доступно.

Сообщение Anonymous »

У меня есть задача исправить/улучшить программу, которая у нас стоит и постоянно выдает исключения OOM при обработке больших файлов (60-90Мб) в памяти. По сути, эта программа представляет собой собственное решение для перемещения файлов из нашей инфраструктуры на клиентский SFTP и наоборот.
Описание высокого уровня:
Данные перемещается в виде файла(ов), содержащих платежные данные. Платежные данные токенизированы на нашей стороне и должны быть не токенизированы, когда они достигают клиента SFTP, или, если мы перемещаем файл ОТ клиента, тогда данные не токенизируются на их стороне, и мы должны токенизировать информацию о платеже ПЕРЕД созданием и сохранением этих данных в виде файла. с нашей стороны. Таким образом, правило, которое мы ДОЛЖНЫ соблюдать, заключается в том, что он ДОЛЖЕН загрузить весь файл в память (мы не можем скопировать его в файл, временный или иной), токенизировать/детокенизировать его в памяти, а затем отправить эти данные из памяти на клиентский SFTP в виде открытого текста или хранить на нашей стороне в токенизированной форме. Ни при каких обстоятельствах нам не разрешается хранить файл с открытым текстом платежных данных на нашей стороне.
В настоящее время это приложение загружает файл целиком в пользовательский класс, который представляет собой более или менее массив строк. , проходит через этот массив, собирая информацию о платеже, а затем отправляет эту информацию о платеже в API токенизации в виде другого массива значений (в данный момент у нас нет возможности пакетировать процесс или частично загружать файлы), затем преобразует результат в MemoryStream и сохраняет его в файл (с токенизированные платежные данные) или загружает их на SFTP (с нетокенизированными платежными данными в виде открытого текста).
Это общая справочная информация о нашем процессе и приложении. Проблема в том, что приложение раньше выдавало OOM при обработке файла размером 90 МБ. Я несколько улучшил код и при компиляции приложения (скомпилировано как x86, не может скомпилироваться как x64 по нескольким причинам). Я также использовал патч editbin.exe /largeaddressaware в исполняемом файле приложения, чтобы он мог обрабатывать адреса размером более 2 ГБ.
Все эти изменения улучшили обработку файлов размером до 120 МБ. . Вероятно, я мог бы внести еще несколько улучшений в код, но наши серверы, на которых работает приложение, имеют 16 или более ГБ ОЗУ и, похоже, не исчерпают ОЗУ при обработке файлов. Более того, при локальной работе у меня те же проблемы с OOM, и у меня все еще остается около 40% свободной оперативной памяти. Немного прочитав эту тему, я чувствую, что это ограничение инфраструктуры x86 и/или .NET.
Ошибка иногда возникает, когда мы отправляем данные в API токенизации, а иногда и это происходит, когда мы пытаемся преобразовать весь файл (как построитель строк) в массив байтов для сохранения в виде файла System.Text.Encoding.UTF8.GetBytes(sb.ToString())
Исключение:
Как ни странно, мы получаем два типа исключений, иногда это простое исключение OOM:

Код: Выделить всё

    System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at System.IO.MemoryStream.set_Capacity(Int32 value)
at System.IO.MemoryStream.EnsureCapacity(Int32 value)
at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)
at xxxxx.ToMemoryStream()
или иногда этот странный вариант, который закрывает приложение, полностью игнорируя любые попытки/уловы:

Код: Выделить всё

The runtime has encountered a fatal error. The address of the error was at 0x73aa2847, on thread 0x5070. The error code is 0xe0004743. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.
Вопрос:
Есть ли более надежный способ загрузки данных в память и не быть ограниченным инфраструктурой x86 или .NET без разделения данных или загружаете частично? Я чувствую, что с 4-8 ГБ доступной оперативной памяти мы не должны исчерпать ее при загрузке файла размером 150 МБ в память. Кажется, существуют и другие способы загрузки данных в память, такие как Memory или MemoryPool, но прежде чем тратить значительное время на исследование всех возможностей, я решил спросить у этого полезного сообщества, на каких направлениях мне следует сосредоточиться.
Использованная технология:
C#, .NET framework 4.5.2
Спасибо
PS: когда это приложение работает, его объем оперативной памяти обычно составляет около 2–3 гигабайта, и, как я уже упоминал ранее, независимо от того, работает ли оно локально или на соответствующем сервере, часто доступно еще 4–8 гигабайт оперативной памяти, когда приложение запускает OOM.

Подробнее здесь: https://stackoverflow.com/questions/793 ... m-is-still
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»