[英]C# Finalizer not freeing unmanaged memory
我有一個MappedMemory
類,它通過Marshal.AllocHGlobal()
分配一塊內存。 該類實現IDisposable
,並且我將其設置為在完成該類時自動處理分配的內存。 但是,它似乎沒有按預期工作。
class 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()
的測試將按Dispose()
工作,並且內存保持恆定的利用率。
但是,對終結器的測試似乎並未釋放分配的內存,並且它泄漏失控,直到內存用盡。 我設置了一個斷點,並調用了Marshal.FreeHGlobal( memoryPtr_ )
。
手動將GC.Collect()
添加到測試中可解決此問題,因此最終看來似乎已釋放了內存,但未回收垃圾?
我對這里發生的事情感到非常困惑。 有人可以解釋一下終結器為什么不釋放內存,以及我如何確保在生產中使用它嗎?
從此處的MSDN文檔中: https : //docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/classes-and-structs/destructors
程序員無法控制何時調用終結器,因為這是由垃圾回收器確定的。 垃圾收集器檢查應用程序不再使用的對象。 如果認為某個對象適合終結,則調用終結器(如果有)並回收用於存儲該對象的內存。
正如您所說的那樣,強制垃圾回收會釋放內存,我懷疑您看到的問題是內存系統上的壓力不足,無法自動運行垃圾回收。 垃圾收集是一個相對昂貴的過程,因此除非有理由這樣做,否則它不會運行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.