Tags
C#, CLR, Dispose, Finalize, finally, garbage collector, GC, memory, memory leak, using
Definition of memory leak
A memory leak occurs when memory is allocated in a program and is never returned to the operating system, even though the program does not use the memory any longer. The following are the four basic types of memory leaks:
- In a manually managed memory environment: Memory is dynamically allocated and referenced by a pointer. The pointer is erased before the memory is freed. After the pointer is erased, the memory can no longer be accessed and therefore cannot be freed.
- In a dynamically managed memory environment: Memory is disposed of but never collected, because a reference to the object is still active. Because a reference to the object is still active, the garbage collector never collects that memory. This can occur with a reference that is set by the system or the program.
- In a dynamically managed memory environment: The garbage collector can collect and free the memory but never returns it to the operating system. This occurs when the garbage collector cannot move the objects that are still in use to one portion of the memory and free the rest.
- In any memory environment: Poor memory management can result when many large objects are declared and never permitted to leave scope. As a result, memory is used and never freed.
When it occurs?
Because of the garbage collection package that is implemented in the Microsoft .NET Framework, it is not possible to have a memory leak in managed code. This suggests two questions: How then can a memory leak occur? Why does it appear that you have a memory leak?
A memory leak can occur in a .NET Framework application when you use unmanaged code as part of the application. This unmanaged code can leak memory, and the .NET Framework runtime cannot address that problem.
Additionally, a project may only appear to have a memory leak. This condition can occur if many large objects (such as DataTable objects) are declared and then added to a collection (such as a DataSet). The resources that these objects own may never be released, and the resources are left alive for the whole run of the program. This appears to be a leak, but actually it is just a symptom of the way that memory is being allocated in the program.
If a collection is declared at the global level of the program, and objects are declared throughout the program and added to that collection, this means that even though the objects are no longer in scope, the objects remain alive because they are still being referenced.
Each time that this occurs, the amount of memory that the program is using increases. The memory does not decrease until the end of the program or the release of the objects from the collection. When you watch the program on a performance monitor, this appears to be a memory leak, but it is not. The program still has control over the memory but has chosen not to release it. The fact that the program still has control prevents this from being a memory leak, but the fact that the program keeps increasing the amount of memory used can make it appear to be a memory leak.