2

I am working on some image processing scripts in .net and came across the following article outlining how to crop, resize, compress, etc.

In the first comment, someone states that the methods used in the article for imaging are notorious for memory leaks:

A quick warning to everybody thinking about using System.Drawing (or GDI+) in an ASP.NET environment. It's not supported by Microsoft and MSDN (as of recently) clearly states that you may experience memory leaks.

Then, in the second comment, the article author effectively says "i've handled that problem":

Just to make clear the code above isn't thrown together. It evolved with time because as you suggested it is too easy to mistakenly create performance issues when using GDI+. Just see how many times I've written 'using' above!

I am wondering how (or if) the use of using effectively handles (or improves) the memory leak problems referenced in the first comment.

GWR
  • 1,878
  • 4
  • 26
  • 44
  • 2
    With `using`, at the end of execution of inner block of code, the object declared in `using` will be disposed automatically – erikscandola Jan 28 '16 at 14:12
  • Possible duplicate of [Uses of "using" in C#](http://stackoverflow.com/questions/75401/uses-of-using-in-c-sharp) – thehennyy Jan 28 '16 at 14:18
  • GDI+ is native; isn't reference counted so there is a risk of memory leak. Memory leaks isn't limited in scope to just _"ASP.NET"_ but rather to **Windows Services** as a whole and IIS _is_ a service. _"[GDI+ functions and classes **are not supported for use within a Windows service**. Attempting to use these functions and classes from a Windows service may produce unexpected problems, such as diminished service performance and run-time exceptions or errors.](https://msdn.microsoft.com/en-us/library/windows/desktop/ms533798(v=vs.85).aspx)"_ –  Jan 28 '16 at 14:21
  • @Micky - yes I am aware of that issue... but the application I am working with uses GDI+ and I can't change away from that at the time being. My code, as it is now, isn't wrapped in the "using" blocks, so I am Just trying to mitigate issues If i can. Looks like I'll be implementing "using" blocks – GWR Jan 28 '16 at 14:23
  • i remember in one of my projects i used wait handle for timing purpose. but i forgot to dispose it and after running program many times for debug the program started to behave strange because timings was not correct any more. i restarted the windows and used dispose and every thing worked fine because all handles were released. – M.kazem Akhgary Jan 28 '16 at 14:23
  • You have a choice, both require changes. Either a) Explicitly call `Destroy()` (or equivalent) on each GDI+ object after you are finished or b) wrap in `using()`. Latter would be my preference. Regardless of how much memory you have in your computer, there is a limit of GDI objects across the OS. –  Jan 28 '16 at 14:24
  • 1
    I'm not saying to _"change away [from GDI+]"_. I'm saying you may need to check your code that GDI+ resources are released appropriately. WinForms apps use GDI+ under the hood for things like fonts and brushes. They too must be released properly. http://stackoverflow.com/questions/9723470/whats-the-upper-limit-on-gdi-objects-for-one-process-in-windows-7 –  Jan 28 '16 at 14:31
  • 1
    Those are indeed often forgotten memory leaks @Micky – Patrick Hofman Jan 28 '16 at 14:42
  • @PatrickHofman Thanks Patrick :) –  Jan 28 '16 at 15:24
  • @Micky - regarding your comment with the 2 choices... would the "using" option be the better one since, on the event of a execution failure it would still release the resources, whereas with the destroy() - the code might never make it to that due to an error or something? – GWR Jan 28 '16 at 17:19
  • Yes. I did say _"Latter [b)] would be my preference"_. –  Jan 28 '16 at 23:49

1 Answers1

7

The using statements don't do anything performance wise. What it does do is calling the Dispose method on the objects the using is declared on.

Calling Dispose will allow unmanaged resources, like those GDI+ creates for your image operations, to be unallocated. This will free up memory and Windows handles. Both can contribute to your application to stop working correct, because if you run out of memory or handles, your program will have trouble running.

A using statement is actually equivalent to (and compiled to this eventually):

var x = ...; // code from using intialization
try
{
    ... // code inside using statement
}
finally
{
    ((IDisposable)x).Dispose();
}

This makes sure the object is disposed, even if an exception occurs.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
  • Just to add something here. A using statement will wrap your code in a try/finally when compiled and calls dispose in the finally block. – Botonomous Jan 28 '16 at 14:16
  • @Botonomous - so this is good, right? in that even if something inside the block fails during execution, the resources are released , correct? – GWR Jan 28 '16 at 14:18
  • 1
    @Botonomous indeed. Expanded on that. – Patrick Hofman Jan 28 '16 at 14:18