Recovery of. net unmanaged resources and recovery of. net managed resources

Source: Internet
Author: User

Recovery of. net unmanaged resources and recovery of. net managed resources

There are two ways to release unmanaged Resources

 

1. destructor

2. Implement the System. IDisposable Interface

 

I. destructor

The constructor can specify certain operations that must be performed when the class instance is created. When the Garbage Collector deletes an object, it can also call the destructor. At the beginning of the destructor, it seems that it is the best place to place the code for releasing unhosted resources and executing general cleanup operations. However, it is not that simple. The running rules of the garbage collector determine that the code to run at a certain time cannot be placed in the destructor. If the object occupies valuable and important resources, release these resources as quickly as possible, so you cannot wait for the garbage collector to release them.

Instance

C # code Replication

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MemRelease
{
    class Program
    {
        ~ Program ()
        {
            // Orders.
        }

        static void Main (string [] args)
        {
        }
    }
}
 

In IL DASM, you will find that there is no such destructuring method. When the C # compiler compiles the destructor, it will implicitly compile the code of the destructor into the corresponding code of the Finalize () method, and ensure that the finalize () method of the parent class is executed. Compile:

  C # code copy
.method family hidebysig virtual instance void
        Finalize () cil managed
{
  // Code size 14 (0xe)
  .maxstack 1
  .try
  {
    IL_0000: nop
    IL_0001: nop
    IL_0002: leave.s IL_000c
  } // end .try
  finally
  {
    IL_0004: ldarg.0
    IL_0005: call instance void [mscorlib] System.Object :: Finalize ()
    IL_000a: nop
    IL_000b: endfinally
  } // end handler
  IL_000c: nop
  IL_000d: ret
} // end of method Program :: Finalize
 

There are several problems with using destructors to release resources:

 

1. Compared with C ++ destructors, the problem with C # destructors is their uncertainty. When a C ++ object is deleted, its destructor will be executed immediately, but due to the way the garbage collector works, it is impossible to determine when the destructor of the C # object will be executed.

2. The execution of the C # destructor will delay the time when the object is finally deleted from memory. Objects with a destructor need to be processed twice before they can be deleted: when the destructor is called for the first time, the object is not deleted, and the object is actually deleted after the second call.

 

Two, IDisposable interface

The IDisposable interface defines a pattern that provides a definite mechanism for releasing unmanaged resources and avoids the problems associated with garbage function inherent in destructors. The IDisposable interface declares a method Dispose (), which takes no parameters and returns void.

 

1. MSDN recommends implementing the IDisposable interface according to the following pattern

  C # code copy
 public class Foo: IDisposable
 {
     public void Dispose ()
     {
        Dispose (true);
        GC.SuppressFinalize (this);
     }
  
     protected virtual void Dispose (bool disposing)
     {
        if (! m_disposed)
        {
            if (disposing)
            {
               // Release managed resources
            }
  
            // Release unmanaged resources
  
            m_disposed = true;
        }
     }
  
     ~ Foo ()
     {
        Dispose (false);
     }
  
     private bool m_disposed;
 }
 

There are actually two functions for releasing resources in .NET objects: Dispose and Finalize

 

(1) The purpose of Finalize is to release unmanaged resources, and Dispose is to release all resources, including managed and unmanaged

 

(2) The void Dispose (bool disposing) function uses a disposing parameter to distinguish whether it is currently being called by Dispose ()

If it is called by Dispose (), then both managed and unmanaged resources need to be released. If it is called by ~ Foo () (that is, C # 's Finalize ()), then only the unmanaged resources need to be released.

 

(3) The Dispose () function is explicitly called by other code and requires the release of resources, and Finalize is called by the GC

When the GC is called, other managed objects referenced by Foo may not need to be destroyed, and even if it is to be destroyed, it will be called by the GC. Therefore, you only need to release unmanaged resources in Finalize. On the other hand, since the managed and unmanaged resources have been released in Dispose (), it is not necessary to call Finalize again when the object is recycled by GC, so call GC.SuppressFinalize (this) in Dispose () to avoid duplication Call Finalize.

 

However, even if you call Finalize and Dispose repeatedly, there is no problem, because the variable m_disposed exists, the resource will only be released once, and the extra calls will be ignored.

 

Finalize, Dispose guarantee

 

(1), Finalize only releases unmanaged resources;

(2), Dispose releases managed and unmanaged resources;

(3) It is no problem to call Finalize and Dispose repeatedly;

(4) Finalize and Dispose share the same resource release strategy, so there is no conflict between them.

 

 

 

 

2. IDisposable example

 

  C # code copy
namespace resource recycling
{
    class Program
    {
        static void Main (string [] args)
        {
            // Use using to implement resource management for classes that implement IDisposable
/ * When you get an object, first determine whether the object implements the IDisposable interface. If it is implemented, it is best to wrap the object with using to ensure that the object is released after it is used up, otherwise a resource leak may occur problem
* /
            using (Telphone t1 = new Telphone ())
            {
                t1.Open ();
                t1.Speak ("hello");
                t1.Bomb ();
                //t1.Dispose();//If the Dispose () method is called here to release resources, then an error occurs during the execution of the t1.Open () method, the telephone line has been cut off, and you can no longer call
                t1.Open ();
                t1.Speak ("I am back!");
            } // After the code is executed here, it will call the Dispose method to recycle resources
            Console.ReadKey ();
        }
    }
    /// <summary>
    /// The Telphone class implements the IDisposable interface
    /// </ summary>
    class Telphone: IDisposable
    {
        /// <summary>
        /// Phone status
        /// </ summary>
        private TelphoneState state;
        /// <summary>
        /// call
        /// </ summary>
        public void Open ()
        {
            if (state == TelphoneState.Disposed)
            {
                throw new Exception ("The telephone line has been cut and cannot be opened!");
            }
            state = TelphoneState.Open;
            Console.WriteLine ("Pick up the phone");
        }
        /// <summary>
        /// speak
        /// </ summary>
        /// <param name = "s"> Speaking content </ param>
        public void Speak (string s)
        {
            if (state! = TelphoneState.Open)
            {
                throw new Exception ("No connection");
            }
            Console.WriteLine (s);
        }
        /// <summary>
        /// hang up the phone
        /// </ summary>
        public void Bomb ()
        {
            state = TelphoneState.Close;
            Console.WriteLine ("Hang up the phone");
        }
        IDisposable members
    }
    /// <summary>
    /// Phone status enumeration
    /// </ summary>
    enum TelphoneState
    {
        Open, Close, Disposed
    }
}
 

Program running results:

 

 

 

 

Three, destructor and IDisposable mixed call example

 

  C # code copy
public class ResourceHolder: IDisposable
{
      private bool isDispose = false;
      
      // Display the called Dispose method
Public void Dispose ()
      {
           Dispose (true);
          GC.SuppressFinalize (this);
       }

       // The actual removal method
Protected virtual void Dispose (bool disposing)
      {
            if (! isDisposed)
           {
      If (disposing)
{
                      // The operation of clearing managed objects is performed here.
                  }
                  // The operation to clear unmanaged objects is performed here
            }
    
IsDisposed = true;
      }

      // Destructor
      ~ ResourceHolder ()
      {
Dispose (false);
      }
}

Teach me, what matters managed resources, what matters unmanaged resources can explain from the most basic concept
In terms of managed resources and unmanaged resources, the first point is clear from memory recovery: managed resources, .net garbage collector automatic recovery, unmanaged resources, and garbage collection period cannot be automatically recovered;
In addition, managed resources are created by the .net core management. Unmanaged resources are created by the .net core by calling other interfaces. .Net cannot be controlled, such as active controls, paint brushes, and paint brushes. These are all created by the .Net call system interface, which can't be controlled, and can only be released by the user.
Finally, what is encapsulated by the .Net kernel and can or can be automatically released is managed resources; if .Net calls external resources, unmanaged resources cannot be automatically released.
 
C # how to manually release memory resources

The codes of the students above are too complicated or theoretical.
Generally speaking, the memory of .Net is automatically managed. If there is too much memory usage, optimization needs to be considered first.
If you really need to collect it manually, you can use System.GC.Collect () to collect it, and the CLR will collect all the variable space that has not been used.
Note that recycling does not necessarily mean a reduction in memory usage in the task manager, which is determined by the characteristics of the operating system.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.