我有一个 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. }}