.NET Coreおよび.NET 5以降では、アプリケーションドメインのシャットダウン中のファイナライザ呼び出しは行われません。 このため、オブジェクトによってはファイナライザ呼び出しが行われないまま.NETプロセスが正常終了することになります。 .NET Frameworkでは、シャットダウン中のファイナライザ呼び出しが行われることが保証されています。 (ファイナライザ呼び出しの抑止が行われている場合は除く)
ガベージコレクタによるファイナライザ呼び出し動作の違いについては、Object.Finalizeメソッドのドキュメントにおいて次のように記載されています。 (引用に際して下線部を強調、太字部分は原文ママ)
How finalization works
(中略)
The garbage collector then calls the Finalize method automatically under the following conditions:
Object.Finalize Method (System) | Microsoft Docs
- After the garbage collector has discovered that an object is inaccessible, unless the object has been exempted from finalization by a call to the GC.SuppressFinalize method.
- On .NET Framework only, during shutdown of an application domain, unless the object is exempt from finalization. During shutdown, even objects that are still accessible are finalized.
.NET/.NET Core/.NET Framework以外のランタイムとして、version 6.12時点でのMonoランタイムでは.NET Frameworkと同様の動作で、ファイナライザ呼び出しが保証されています。
例として以下のコードで動作を確認すると次のようになります。 .NET Core/.NET 5以降で実行した場合は、プロセス終了までの間にファイナライザの呼び出しが行われません。 なお、GC.WaitForPendingFinalizersでファイナライザ呼び出しを待機する場合(無効化してあるコード)は、ファイナライザ呼び出しが行われます。
using System;
class Resource {
public Resource() => Console.WriteLine("constructed");
~Resource() => Console.WriteLine("finalized");
}
class Sample {
static void Main()
{
Console.WriteLine(System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription);
static void AllocateAndRelease() => new Resource();
AllocateAndRelease();
#if false
GC.Collect();
GC.WaitForPendingFinalizers();
#endif
}
}
.NET 5.0.0-rc.1.20451.14 constructed
.NET Core 3.1.8 constructed
.NET Framework 4.8.4250.0 constructed finalized
Mono 6.12.0.90 (tarball Fri Sep 4 14:02:38 UTC 2020) constructed finalized
GC.Collectメソッド・GC.WaitForPendingFinalizersメソッドについては§.ガベージコレクタへの要求 (GCクラス)を参照してください。