I am trying to understand the concept of memory leaks better. Can anyone point up some useful information that can help me better understand exactly what memory leaks are and how I would find them in my code.
相关问题
- Sorting 3 numbers without branching [closed]
- Graphics.DrawImage() - Throws out of memory except
- Why am I getting UnauthorizedAccessException on th
- 求获取指定qq 资料的方法
- How to know full paths to DLL's from .csproj f
A very good read is Everybody thinks about garbage collection the wrong way.
In general, a memory leak, or any resource leak, is whenever the program allocates memory (or any other resource) and then omits to deallocate it when finished with it. In native application memory leak is the most common resource leak and can happen when the resource reference (the pointer to the allocated block) goes out of scope and is destroyed, but allocated resource (the memory block) does not get destroyed. In this case the resource (memory) is leaked because the program has lost the ability to release it, even if it wants to, because it no longer remembers the location of the resource (the address of the block).
In managed applications memory leaks are a bit trickier. Since the runtime can track references to resources automatically, it can also understand when a resource (an object) is no longer referenced by any active part of the application (there is no chain of references from a stack frame to that resource on any thread) and thus the runtime can understand when is safe to collect the objects no longer references by the application. So in managed world a a 'leak' would occur when you believe that the applicaiton no longer references an object (and thus it can be collected by the runtime) but in fact, through some chain of references, you do have a reference to it and thus it cannot be collected.
I highly recommend Raymond Chen's article linked above, is very very illuminating.
When memory is assignned to an application, the application has an obligation to release that memory back to the operating system so that it can be re-used by other applications. A memory leak occurs when an application does not release that memory, thus preventing it from being reallocated.
For managed code, the garbage collector tracks references to the objects created by an application. For most situations the CLR will handle memory allocation and deallocation transparently and in a reasonable way on behalf of the running process. However .NET developers still need to consider resource management as there are still situations in which memory can leak despite the work of the garbage collector.
Consider the following code:
Widget widget = new Widget();
The above line of code creates a new instance of the Widget class and the widget field is assigned a reference to that object. GC keeps track of the references associated with each object and deallocates the memory of objects for which there are no strong references.
It's worth mentioning that the CLR's garbage collection will only collect managed objects, .NET code can and does frequently make use of unmanaged resources which can not be garbage collected automatically.
Unmanaged resource leaks occur when the object for which those resources were allocated fails to correctly deallocate them before the last reference to those resources goes out of scope, which leaves the resources allocated, but unreferenced and therefore unusable to the application.
Classes which reference unmanaged resources directly should ensure that those resources are correctly deallocated. An example of doing this would look something like this:
The
disposing
parameter is false when being called from a finalizer. This is to prevent managed resources being used from within the finalizer as managed references should be considered invalid at that stage.Note also that the
Dispose()
method callsGC.SuppressFinalize(this)
which prevents the finalizer running for that instance. This is done because the resources that would have been deallocated in the finalizer were deallocated in the Dispose call making a fializer invocation unnecessary.Client code that makes use of classes that handle unmanaged resources (or any class that implements IDisposable) should do so within a
using
block to ensure that theIDisposable.Dispose
is called when access to the resource is no longer needed as this will take care of both managed and unmanaged resources and, in the case of the example above, ensure that a very expensive call to the finalizer is not made.Appoligies for my rambling. I'll stop now.
A traditional memory leak happens when you allocate memory, and then somehow "forget" to free it. In old C++ code, that means calling
new
without a correspondingdelete
. In C, it meant a call toalloc()
/malloc()
without a correspondingfree()
.In .Net, you don't get memory leaks in the traditional sense, because you aren't supposed to release memory yourself. Instead, you rely on the garbage collector to release it for you. However, this doesn't mean that you'll never lose track of memory. There are several ways you might accidentally keep a reference around that prevents the garbage collector from doing it's job. These include global variables (especially lists, dictionaries, and other collection types that might be used to "cache" objects), event handlers that hang on to memory, recursive history references, and the large object heap.
It's important to also note here that just because you see a pattern of increasing memory use in .Net, it doesn't necessarily mean your app is leaking memory. In cases of low overall memory pressure the garbage collector could just be opting to save time by not collecting yet, or by collecting within the process's existing address space only without returning the memory to the operating system.
"Memory leak" should be defined as "memory that is used when YOU believe it should not be used" to apply to garbage collected languages/runtimes as C#/Java.
Traditionally "memory leak" is defined as memory that is not properly deallocated (see wikipedia link in other answers) which generally does not happen for garbage collected environments. Note that due to problems with runtime even garbage collected languages can leak memory - i.e. even if JavaScript is garbage collected language, it was easy to leak large amount of JavaScript objects in Internet Explorer's JavaScript runtime.
There are many kinds of memory leaks, but in general the term refer to some kind of resource that is no longer used, but still takes up memory. If you have many of those your application takes a lot of memory and eventually you run out of it.
In C#, these are some common memory leaks:
Dispose()
on allIDisposable
objects. Use theusing
statement.A memory leak occurs when your program dynamically allocates memory that doesn't get properly deallocated after you're done using it. If you have a program that continuously does this, your leak will get bigger and bigger and pretty soon your program is taking up all your RAM.