Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>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.</p> <p>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.</p> <p>Consider the following code:</p> <p><code>Widget widget = new Widget();</code></p> <p>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.</p> <p>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. </p> <p>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.</p> <p>Classes which reference unmanaged resources directly should ensure that those resources are correctly deallocated. An example of doing this would look something like this:</p> <pre><code>public void ManagedObject : IDisposable { //A handle to some native resource. int* handle; public ManagedObject() { //AllocateHandle is a native method called via P/Invoke. handle = AllocateHandle(); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if (disposing) { //deal with managed resources here FreeHandle(handle); } } ~ManagedType() { Dispose(false); } } </code></pre> <p>The <code>disposing</code> 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. </p> <p>Note also that the <code>Dispose()</code> method calls <code>GC.SuppressFinalize(this)</code> 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.</p> <p>Client code that makes use of classes that handle unmanaged resources (or any class that implements IDisposable) should do so within a <code>using</code> block to ensure that the <code>IDisposable.Dispose</code> 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.</p> <p>Appoligies for my rambling. I'll stop now.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload