我有一个类,它通过分配一个内存块。该类实现,我已将其设置为在类最终确定时自动释放分配的内存。但是,它似乎未按预期工作。MappedMemoryMarshal.AllocHGlobal()IDisposableclass MappedMemory : IDisposable{ private bool disposed_ = false; private IntPtr memoryPtr_; public MappedMemory( int capacity ) { memoryPtr_ = Marshal.AllocHGlobal( capacity ); } ~MappedMemory() { Dispose( false ); } public void Dispose() { Dispose( true ); GC.SuppressFinalize( this ); } protected virtual void Dispose( bool disposing ) { if ( !disposed_ ) { if ( disposing ) { // Clear managed resources } Marshal.FreeHGlobal( memoryPtr_ ); } disposed_ = true; }}我已经编写了两个测试来确保内存被正确释放:public MappedMemory_finalizer_frees_memory(){ for( var i = 0; i < 1e8; i++ ) { var memory = new MappedMemory( 128 ); }}public MappedMemory_dispose_frees_memory(){ for( var i = 0; i < 1e8; i++ ) { var memory = new MappedMemory( 128 ); memory.Dispose(); }}运行测试时,手动调用的测试将按预期工作,并且内存保持恒定利用率。Dispose()但是,终结器的测试似乎没有释放分配的内存,并且在内存耗尽之前会失控泄漏。我设置了一个断点,并且命中了对的调用。Marshal.FreeHGlobal( memoryPtr_ )手动添加到测试中可以解决问题,因此最终看起来内存已解除分配,但未被垃圾回收?GC.Collect()我对这里发生的事情感到非常困惑。有人可以解释为什么终结器不能释放内存,以及我如何确保它在生产中释放内存吗?
1 回答

白猪掌柜的
TA贡献1893条经验 获得超10个赞
从 MSDN 文档中,此处为:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/destructors
程序员无法控制何时调用终结器,因为这是由垃圾回收器确定的。垃圾回收器检查应用程序不再使用的对象。如果它认为某个对象符合完成条件,它将调用终结器(如果有)并回收用于存储该对象的内存。
正如您所说,强制垃圾回收会释放内存,我怀疑您看到的问题是内存系统上没有足够的压力来导致垃圾回收自动运行。垃圾回收是一个相对昂贵的过程,因此除非有理由这样做,否则它不会运行。
- 1 回答
- 0 关注
- 145 浏览
添加回答
举报
0/150
提交
取消