当前位置: 代码迷 >> .NET Framework >> 非托管资源占用内存的大小,GC 知道吗?解决方法
  详细解决方案

非托管资源占用内存的大小,GC 知道吗?解决方法

热度:143   发布时间:2016-05-02 01:03:26.0
非托管资源占用内存的大小,GC 知道吗?
我有一个 C++/CLI 对象。形如:

C# code
public ref class DStructure{private:    double* array;protected:    !DStructure()    {        delete[] array;    }public:    DStructure()    {        array = new double[1000];    }    ~DStructure()    {        delete[] array;    }};


当我这样运行的时候,内存不断泄漏,然后崩溃了。

C# code
while(true){    DStructure^ ds = gcnew DStructure();}


但是我这样运行的时候,程序就跑得好好的,不会崩溃,没有泄漏。

C# code
while(true){    DStructure^ ds = gcnew DStructure();    GC::Collect();}


这里我不明白的是,在第一种情况下,内存占满后,GC 为什么不会去执行回收,而是坐看着内存爆掉呢?是不是内部它是用“总内存大小 - 托管对象占用内存大小”来计算剩余内存的,所以它看不到非托管的部分?请各位大大赐教~


------解决方案--------------------
学习。
------解决方案--------------------
不行.net framwork不知道非托管资源。

可以实现IDisposable 接口

C# code
using System;using System.ComponentModel;// The following example demonstrates how to create// a resource class that implements the IDisposable interface// and the IDisposable.Dispose method.public class DisposeExample{    // A base class that implements IDisposable.    // By implementing IDisposable, you are announcing that    // instances of this type allocate scarce resources.    public class MyResource: IDisposable    {        // Pointer to an external unmanaged resource.        private IntPtr handle;        // Other managed resource this class uses.        private Component component = new Component();        // Track whether Dispose has been called.        private bool disposed = false;        // The class constructor.        public MyResource(IntPtr handle)        {            this.handle = handle;        }        // Implement IDisposable.        // Do not make this method virtual.        // A derived class should not be able to override this method.        public void Dispose()        {            Dispose(true);            // This object will be cleaned up by the Dispose method.            // Therefore, you should call GC.SupressFinalize to            // take this object off the finalization queue            // and prevent finalization code for this object            // from executing a second time.            GC.SuppressFinalize(this);        }        // Dispose(bool disposing) executes in two distinct scenarios.        // If disposing equals true, the method has been called directly        // or indirectly by a user's code. Managed and unmanaged resources        // can be disposed.        // If disposing equals false, the method has been called by the        // runtime from inside the finalizer and you should not reference        // other objects. Only unmanaged resources can be disposed.        protected virtual void Dispose(bool disposing)        {            // Check to see if Dispose has already been called.            if(!this.disposed)            {                // If disposing equals true, dispose all managed                // and unmanaged resources.                if(disposing)                {                    // Dispose managed resources.                    component.Dispose();                }                // Call the appropriate methods to clean up                // unmanaged resources here.                // If disposing is false,                // only the following code is executed.                CloseHandle(handle);                handle = IntPtr.Zero;                // Note disposing has been done.                disposed = true;            }        }        // Use interop to call the method necessary        // to clean up the unmanaged resource.        [System.Runtime.InteropServices.DllImport("Kernel32")]        private extern static Boolean CloseHandle(IntPtr handle);        // Use C# destructor syntax for finalization code.        // This destructor will run only if the Dispose method        // does not get called.        // It gives your base class the opportunity to finalize.        // Do not provide destructors in types derived from this class.        ~MyResource()        {            // Do not re-create Dispose clean-up code here.            // Calling Dispose(false) is optimal in terms of            // readability and maintainability.            Dispose(false);        }    }    public static void Main()    {        // Insert code here to create        // and use the MyResource object.    }}
  相关解决方案