返回没有内存泄漏的base64映像ASP.NET MVC 3

che*_*ova 5 c# asp.net-mvc razor asp.net-mvc-3

我有一些图像作为base64字符串存储在数据库中,需要从MVC控制器返回它们.如果没有内存泄漏,我怎么能这样做?

以前我用过这个:

return File(Convert.FromBase64String(pictureString), "image/jpeg");
Run Code Online (Sandbox Code Playgroud)

但是,w3wp进程开始使用一大堆内存来处理几张照片.

有没有正确的方法来做到这一点?目前我决定只将每个图像设置为数据:image/jpg; base64,string_here并且它使用的内存要少得多......但是加载页面似乎也要慢得多.

任何帮助表示赞赏.

Dar*_*rov 8

以前我用过这个:

此代码中没有泄漏.问题是它在将整个图像流式传输到响应之前将其加载到内存中.内存引起你观察到的w3p进程是正常的,一旦垃圾收集器踢它就会清理它.除非你正在提供一些非常大的图像,否则你不应该真的担心这一点.

您的设计的问题是您使用base64意味着您需要加载整个内容才能将其解码回字节数组.另一种方法是将图像作为原始数据存储在数据库中,然后使用流以块的形式读取它并立即将这些块写入响应.这样,只有当前正在处理的在给定的时间点被加载到存储器中.

我可能建议您使用的另一种方法是不将图像存储在数据库中,而是将它们存储在文件系统中,并且只存储数据库中图像的路径.然后在您的控制器操作中,您所要做的就是return File(pathToTheImage, "image/jpeg").

作为额外的优化,如果这些图像不经常更改,您可以将适当的输出缓存添加到为这些图像提供服务的控制器操作中,以避免每次都出现这种情况.


Ale*_*kov 1

+1达林·季米特洛夫的评论。

如果图像/base64 编码数据超过 85K,它将分配在 LOH(大型对象堆)上。由于需要等待第 2 代收集,此类分配的 GC 成本更高。

如果您必须继续使用 Base64 编码图像,另一种方法是实现您自己的流,该流从块中的 Base64 编码值读取数据,以避免分配第二大内存块。如果您可以读取 chunk 中的字符串,您也将能够避免在 LOH 上分配对象,并且可能只是重用真正小的缓冲区来读取/解码。