Возврат изображения base64 без утечки памяти ASP.NET MVC 3

У меня есть некоторые изображения, хранящиеся в базе данных в виде строк base64, и мне нужно вернуть их из контроллера MVC. Как я могу сделать это без утечки памяти?

Раньше я использовал это:

return File(Convert.FromBase64String(pictureString), "image/jpeg");

Однако процесс w3wp начинает использовать целую кучу памяти для нескольких фотографий.

Есть ли правильный способ сделать это? В настоящее время я решил просто установить для каждого изображения значение data:image/jpg;base64,string_here, и оно использует намного меньше памяти... но, похоже, загрузка страницы также намного медленнее.

Любая помощь приветствуется.


person chemicalNova    schedule 20.09.2011    source источник
comment
Насколько велики ваши изображения, т.е. какова длина строки в кодировке base 64 и JPEG?   -  person Codo    schedule 20.09.2011


Ответы (2)


+1 К комментарию Дарина Димитрова.

Если изображения / данные, закодированные в base64, превышают 85 КБ, они будут размещены в LOH (куча объектов хранения). GC для таких распределений дороже из-за необходимости ждать сбора 2-го поколения.

Другой подход, если вам нужно продолжать использовать изображения, закодированные в base64, заключается в реализации собственного потока, который считывает данные из закодированного в Base64 значения по частям, чтобы избежать выделения второго большого блока памяти. Если вы можете читать строку в чанке, вы также сможете избежать выделения объектов в LOH и, возможно, просто повторно использовать очень маленькие буферы для чтения/декодирования.

person Alexei Levenkov    schedule 20.09.2011
comment
Спасибо за информацию. Я отметил это как ответ, потому что изображения загружались размером более 85 КБ. С тех пор мне пришлось переписать все приложение (я не писал его с самого начала :/). Спасибо за все советы! - person chemicalNova; 13.10.2011

Раньше я использовал это:

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

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

Еще один подход, который я могу предложить вам, заключается в том, чтобы вообще не хранить изображения в базе данных, а хранить их в файловой системе и хранить в базе данных только путь к изображению. Затем в вашем действии контроллера все, что вам нужно сделать, это return File(pathToTheImage, "image/jpeg").

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

person Darin Dimitrov    schedule 20.09.2011
comment
Спасибо за ваши предложения .. они определенно помогли мне при переписывании приложения! - person chemicalNova; 13.10.2011