Возвращение образа base64 без утечки памяти ASP.NET MVC 3 - PullRequest
5 голосов
/ 20 сентября 2011

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

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

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

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

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

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

Ответы [ 2 ]

8 голосов
/ 20 сентября 2011

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

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

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

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

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

1 голос
/ 20 сентября 2011

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...