問題タブ [suppressfinalize]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - SuppressFinalize を複数回呼び出す
何度も電話することのデメリットはありますGC.SuppressFinalize(object)
か?Disposeパターン
の
保護されたDispose(bool)
メソッドは、以前に呼び出されたかどうかをチェックしますが、パブリックメソッドにはそのようなチェックはありません。Dispose()
インスタンスのDispose()
メソッドを複数回呼び出しても問題ありませんか?MyClass
c# - ファイナライザーのオーバーヘッド - Dispose で SuppressFinalize を使用する場合と使用しない場合
以下を仮定します。
- クラスはメンバーのみを管理しています。
- 一部のメンバーは実装し
IDisposable
ます。 - クラスは
sealed
- クラスはアンマネージ リソースから派生したり、追加したりすることはできません。 - オブジェクトは
using
ステートメント内で使用されます。つまりDispose()
、完了時に呼び出されます。
IDisposable
このクラス には 3 つの可能な実装があります。
- メンバーを
Dispose
呼び出す最小限のメソッド - NO finalizer。Dispose()
IDisposable
IDisposable
Finalizer を使用した標準的な実装ですが、通常の呼び出しがありません。GC.SuppressFinalize(this)
Dispose()
IDisposable
Finalizer (およびGC.SuppressFinalize(this)
call in ) を使用した完全な標準実装Dispose()
。
次の記述は正しいですか? 私はこれを正しく理解しましたか?
- ケース A. のオーバーヘッドは B. および C. よりもわずかに少なくなります。これは、オブジェクトにファイナライザーがないため、GC のファイナライズ キューに入らないためです。GC はコレクションの早い段階でこのオブジェクトを消去できるため、オーバーヘッドはありません。
- ケース B. オブジェクトにファイナライザーがあるため、最終的に GC のファイナライザー キューに入り、ファイナライザーが呼び出されます (抑制されていないため) - ファイナライザーは既に呼び出されているため何もしない dispose を呼び出します。これにより、オブジェクトがファイナライザー キューにあるというわずかなオーバーヘッドと、ファイナライザー呼び出しのごくわずかなオーバーヘッドが発生します。
- ケース C. オブジェクトにファイナライザーがあるため、GC のファイナライザー キューに入れられます。dispose
SuppressFinalize
が呼び出されたため、ファイナライザーは実行されません。この場合でも、オブジェクトがファイナライザー キューに入るというわずかなオーバーヘッドが発生しますが、ファイナライザーは実際には実行されません。
ここでの重要な点は、「呼び出すことでファイナライザーのオーバーヘッドを回避した」と考えたくなるということですが、それは正しくないSuppressFinalize
と思います (明確にしたいと思います)。ファイナライザー キューにあるオブジェクトのオーバーヘッドは依然として発生します。回避しているのは、実際のファイナライザー呼び出しだけです。一般的なケースでは、「私は既に何もしていません」というだけです。
注: ここでいう「完全な標準IDisposable
実装」とは、アンマネージド リソースとマネージド リソースの両方のケースをカバーするように設計された標準実装を意味します (ここでは、マネージド オブジェクト メンバーしかないことに注意してください)。