MORE INFORMATION
Memory leaks can cause an application to run out of
resources and can cause an application to crash. It is important to identify
memory leaks. The problem of memory leaks has plagued developers in C and C++
for years. In Microsoft Visual Studio 2005 or in Microsoft Visual Studio .NET, a comprehensive garbage collection
package and managed memory can stop memory leaks, but, under some
circumstances, a program may appear to be leaking memory.
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.
Discussion
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.
For example, you have a
DataSet. Every time that a new query is run, you add a new
DataTable element to that
DataSet to hold the data that is returned. If there are large amounts of
data that you never dispose of, the data stays alive as long as the
DataSet is still in use. If this occurs enough times, it is possible to
run out of memory. This is not a memory leak, but instead it is a problem in
managing the memory. See the following code example:
Dim DS As DataSet
Dim cn As New SqlClient.SqlConnection("data source=localhost;initial catalog=Northwind;integrated security=SSPI")
cn.Open()
Dim da As New SqlClient.SqlDataAdapter("Select * from Employees", cn)
Dim i As Integer
DS = New DataSet()
For i = 0 To 1000
da.Fill(DS, "Table" + i.ToString)
Next
Note This example is just a snippet of code. This example assumes
that Microsoft SQL Server is installed on the local computer and that the user
who is running this code has access to the
Northwind database that is included with SQL Server.
Although
this code is obviously inefficient and not practical, it is meant to
demonstrate that if objects are added to a collection (such as adding the
tables to the
DataSet collection), the objects are kept active as long as the
collection remains alive. 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.
Symptoms of memory leak
When the amount of memory that a program is using continues to
increase during the execution, this is a symptom of a memory leak. (You can
watch this count of memory through a performance monitor.) The amount of memory
that the program uses can eventually cause the program to run out of resources
and to crash.