We have done some investigation on largest file found in our test set, and had successfully freed memory after loading it.
Dispose(), by spec, should release unmanaged resources. In our case we do release file or stream the image has been loaded from. It is often expected that Dispose() fully clears the object and makes it unusable, but spec doesn’t dictate that and we don’t do that, as such, all loaded and processed data remains in memory.
To unload that data and free memory, one just has to null all references to loaded image and call garbage collection. Here is an example.
Image img = null;
img = Image.Load(filename);
//do work here
img = null;
GC.Collect(3); //mark objects in all heaps and trigger finalizers
GC.Collect(3);//actual cleanup should happen now.
There is a nuance with using() statement. It holds a hidden reference to variable it declares, and it is not cleared until one returns from method where using() is used. As such, only call garbage collection after return from this method, like in the following example:
void ProcessImageAndClean(string filename)
void ImageProcessingMethod(string filename)
using (Image img = Image.Load(filename))
//do your work here