The question Memory leak with java has been answered but is creating a memory leak possible in .net?
What would be an example?
The question Memory leak with java has been answered but is creating a memory leak possible in .net?
What would be an example?
for(int i = 0; i < 10; i++)
{
IntPtr imageData = Marshal.AllocHGlobal(1024*1024);
}
This will result in 10 MB leaked memory for example. Everything unmanaged can leak, its hard to get something managed to leak memory, if at all.
As far as I see, you can "leak" memory by creating a separate AppDomain each time a specific operation is executed and forget to unload that AppDomain after the operation is finished. At least, they don't seem to be unloaded automatically: http://nikcodes.com/2013/01/18/understanding-appdomain-unloads-old-lessons-learned-anew/
But one may argue this isn't a memory leak, because the AppDomains are stored internally and not "lost". However, I can't find a way to get all existing AppDomains and/or check if they are still in use to unload them. Plus, it can get quite nasty, depending on the size of Assemblies loaded into the AppDomain.
Edit:
You can list all AppDomains, but it is technically not in .Net:
List AppDomains in Process
so if you argue Marshal.AllocHGlobal(1024*1024);
is a memory leak but not in .Net, then "unreferenced" AppDomains are a memory leak because the solution is not in .Net.
; P
There are tons of philosophical discussions out there, whether unused references are to be called "resource leak" instead of "memory leak." For me, the AppDomain example might be a true memory leak, if there is no way of accessing the existing AppDomains.
While not technically a leak, you can still observe the same symptoms (running out of memory) when you inadvertently keep references to objects you don't actually need any more. For instance if you have a static cache of previously computed data:
static List<string> previousResults = new List<string>();
public string GetSomeResult(int arg)
{
string s = DoSomething(arg);
previousResults.Add(s);
return s;
}
Very stupid example, but it shows the point: When nobody ever clears the list, it will grow forever. I'm calling this a memory leak in .NET, even if it technically isn't one (as the objects are still addressable). There are more subtle ways of observing the same behavior where you don't see that you're still keeping references in the first place.
The most common memory leak I see in .NET is a static object that never goes away. This is common for Singleton objects, but it can also be a mistake from a misunderstanding of how static objects work.
Another, sneakier example of a memory leak is registering for a static event. For example, all of the events in the SystemEvents class are static. If an object registers itself for this event, it must de-register itself, or else the object will never be garbage collected.
We actually had that happen when someone registered a form to listen for the SystemEvents.SessionEnding event. These events are static. They hold on to a static list of delegates that are invoked when the event occurs. Even if the object is disposed, and all of your references to this object are set to null, the static event will continue to hold onto it, so the object will never be garbage collected. And since that object is preserved, all objects it references stay alive, too.
Here's a good way to create a true memory leak (objects inaccessible by running code but still stored in memory) in pure Java:
The application creates a long-running thread (or use a thread pool to leak even faster).
The thread loads a class via an (optionally custom) ClassLoader.
The class allocates a large chunk of memory (e.g. new byte[1000000]), stores a strong reference to it in a static field, and then stores a reference to itself in a ThreadLocal. Allocating the extra memory is optional (leaking the Class instance is enough), but it will make the leak work that much faster.
The thread clears all references to the custom class or the ClassLoader it was loaded from. Repeat.