Base64 image return without ASP.NET MVC 3 memory leak

I have some images stored in the database as base64 strings and need to be returned from the MVC. How can I do this without a memory leak?

I used to use this:

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

However, the w3wp process begins to use a whole bunch of memory for several photos.

Is there a proper way to do this? Currently, I decided to simply set each image to data: image / jpg; base64, string_here, and it uses a lot less memory .. but it seems to load the page much slower.

Any help is appreciated.

+4
source share
2 answers

+1 Comment Darina Dimitrova.

If the images / base 64 encoded data is more than 85 KB, they will be allocated to LOH (a bunch of objects). GC for such distributions is more expensive due to the need to wait for generation 2 generation.

Another approach, if you need to use base64 encoded images, is to implement your own stream, which reads the data from the encoded Base64 value in pieces, to avoid allocating a second large block of memory. If you can read a line in chunck, you can also avoid allocating objects to the LOH and potentially just reusing really small read / decode buffers.

+1
source

I used to use this:

There is no leak in this code. The problem is that it loads the entire image into memory before sending it back. The memory that you observe in the w3p process is normal, and as soon as the garbage collector knocks it out, it will clear it. You should not worry about this unless you are displaying very large images.

The problem with your design is that you are using base64, which means you need to load all the content before you can decode it back into an array of bytes. Another approach would be to save the images as raw data in your database, and then use the streams to read in chunks and immediately write these fragments in response. Thus, only the currently loaded fragment is loaded into memory at a certain point in time.

Another approach that I can offer you is not to store images in the database, but to store them in the file system and save only the path to the image in the database. Then in the action of your controller all you need to do is return File(pathToTheImage, "image/jpeg") .

As an additional optimization, if these images do not change frequently, you can add the correct output caching to the controller action serving these images in order to hit it each time.

+8
source

All Articles