C#管理されたリソースと管理されていないリソース(リファレンス8)C#リソースのリリース

この記事は以下から転送されます:https : //www.cnblogs.com/lyh523329053/articles/8051560.html

C#リソースのリリース

 

.NETプログラミングプロセスでは、メモリガベージコレクションの大部分はCLR(共通言語ランタイム)によって自動的に収集されますが、コードのリサイクルが必要なものも多数あります。管理対象と管理対象外の基本的な知識を習得すると、特定の状況によって引き起こされるプログラムの異常を効果的に回避できます。

1.管理および非管理

1.1管理されているものと管理されていないもの

マネージコードは、Visual Basic .NETおよびC#コンパイラによってコンパイルされたコードです。コンパイラーは、コードを中間言語(IL)にコンパイルします。コンピューターで直接実行できるマシンコードではありません。中間言語は、アセンブリと呼ばれるファイルにカプセル化されます。アセンブリには、作成したクラス、メソッド、プロパティ(セキュリティ要件など)を説明するすべてのメタデータが含まれます。このアセンブリを別のサーバーにコピーして展開できます。一般的に言えば、このコピーアクションは、展開プロセスにおける唯一の操作です。

マネージコードは、共通言語ランタイム(CLR)で実行されますこのランタイムライブラリは、実行中のコードにさまざまなサービスを提供します。一般的に、このランタイムライブラリは、アセンブリを読み込んで検証し、中間言語が正しいことを確認します。特定のメソッドが呼び出されると、ランタイムライブラリは特定のメソッドをローカルコンピューターの操作に適した機械コードにコンパイルし、次の呼び出しのためにコンパイルされた機械コードをキャッシュします(これはジャストインタイムコンパイルです)。アセンブリの実行中、ランタイムはセキュリティ、メモリ管理、スレッド管理などのさまざまなサービスを提供し続けます。このプログラムは、ランタイムで「ホスト」されます。Visual Basic .NETおよびC#では、マネージコードのみを生成できます。これらの言語でプログラムを作成する場合、生成されるコードはマネージコードです。

管理対象リソース:通常、CLR(共通言語ランタイム)によって制御されるメモリリソースを指し、これらのリソースはCLRによって管理されます。.netクラスライブラリのリソースと見なすことができます。

アンマネージリソース:CLRによって制御および管理されないリソース。

管理対象リソースの場合、GCはガベージコレクションを担当します。アンマネージリソースの場合、GCはアンマネージリソースのライフタイムを追跡できますが、解放する方法がわからないため、現時点では手動で解放する必要があります。

1.2どのリソースが管理されていませんか?

アンマネージコードは、Visual Basic 6、Visual C ++ 6など、Visual Studio .NET 2002のリリース前に作成されたコードです。最悪のことは、まだハードディスク上にあり、15年以上の歴史を持つ古いCコンパイラによって生成されたコードでさえ、アンマネージコードであることです。アンマネージコードはターゲットコンピューターの機械的コードに直接コンパイルされます。これらのコードは、コンパイル元のコンピューター、または同じプロセッサまたはほぼ同じプロセッサを搭載した他のコンピューターでのみ実行できます。アンマネージコードは、セキュリティやメモリ管理など、一部のランタイムが提供するサービスを利用できません。アンマネージコードがメモリ管理などのサービスを実行する必要がある場合は、オペレーティングシステムのインターフェイスを明示的に呼び出す必要があります。一般的には、Windows SDKが提供するAPIを呼び出して実現します。最近の状況では、アンマネージプログラムはCOMインターフェイスを介してオペレーティングシステムサービスを取得します。Visual Studioプラットフォームの他のプログラミング言語とは異なり、Visual C ++はアンマネージプログラムを作成できます。プロジェクトを作成し、名前がMFC、ATL、またはWin32で始まるプロジェクトタイプを選択すると、このプロジェクトはアンマネージプログラムを生成します。

要約すると、アンマネージコードは、共通言語ランタイム環境(CLR)の外部で実行され、オペレーティングシステムによって直接実行されるコードですアンマネージコードは、ガベージコレクション、型チェック、セキュリティサポートなどの独自のサービスを提供する必要があります。これは、共通言語ランタイムからこれらのサービスを取得するマネージコードとは異なります。

一般的に言えば、CLRによって制御および管理されないのはリソースです。

含む:ファイルストリーム、イメージグラフィック、データベース接続、ネットワーク接続、システムウィンドウハンドル、プリンターリソースなど。通常、このようなリソースはヒープ上に存在しません。オペレーティングシステムのリソースと見なすことができるAPIのセット。

原則:クラスがデータベース接続、ファイルハンドルなどのアンマネージリソースを使用する場合、これらのリソースを次のように解放する必要があります。

1.3マネージドコードの実行プロセス

  1. コンパイラを選択します。共通言語ランタイムが提供する利点を得るには、ランタイム用の1つ以上の言語コンパイラ(Visual Basic、C#、Visual C ++、JScript、または多くのサードパーティコンパイラ(Eiffel、Perlなど)を使用する必要があります。 COBOLコンパイラ)。ランタイムは多言語実行環境であるため、さまざまなデータ型と言語関数をサポートしています。使用する言語コンパイラは、最初に使用可能なランタイム関数を決定し、次にこれらの関数を使用してコードを設計します。コンパイラーは(ランタイムではなく)コードが使用する必要のある構文を確立します。コンポーネントが他の言語で記述されたコンポーネントで完全に使用可能でなければならない場合、コンポーネントのエクスポートタイプは、共通言語仕様(CLS)に含まれる言語機能のみを公開する必要があります。
  2. ソースコードをコンパイルしてMicrosoft Intermediate Language(MSIL)に変換し、必要なメタデータを生成します。
  3. 実行時に、リアルタイム(JIT)コンパイラはMSILをネイティブコードに変換します。このコンパイルプロセス中、コードは、MSILとメタデータをチェックしてコードがタイプセーフであると判断できるかどうかを確認する検証プロセスを実行する必要があります。
  4. コードの実行:共通言語ランタイムは、実行を可能にし、実行中に使用できるさまざまなサービスの構造を提供します。

2.アンマネージリソースを解放するにはどうすればよいですか?

.NETの場合、リソースを解放する標準的な方法は次のとおりです。

(1)IDisposableインターフェイスを継承します。

(2)Dispose()メソッドを実装します。このメソッドでは、マネージリソースとアンマネージリソースが解放され、オブジェクト自体がガベージコレクターから削除されます(ガベージコレクターはこのリソースをリサイクルしません)。

(3)クラスデストラクタ実装し、その中でアンマネージリソースを解放します。

 Dispose()メソッドのいくつかのパラメーターの説明:

A.パラメータがtrueの場合、すべてのリソースが解放され、ユーザーのみが呼び出すことができます

  パラメータがfalseの場合、ガベージコレクタによってのみ自動的に呼び出されるアンマネージリソースを解放することを意味します。

C.サブクラスに独自のアンマネージリソースがある場合、この関数をオーバーロードして、独自のアンマネージリソースリリースを追加できます。

D.ただし、この関数のオーバーロードでは、基本クラスのバージョンが呼び出され、基本クラスのリソースが正常に解放されるようにする必要があります。 

2.1 Disposeの実装方法

...書く時間があるとき

2.2リソース解放の例

2.2.1データベース接続の解放

(1)間違った練習:  

SqlConnection conn = new SqlConnection();
//何かをする;
conn.Dispose();

このコードでは、例外conn.Dispose()が時間内に実行に失敗すると、接続が時間内に閉じられなくなります。

(2)正しいアプローチ: 

コードをコピー
SqlConnection conn = new SqlConnection();
試す
{
    //何かをする;
}
最後に
{
    conn.Dispose();
}
コードをコピー

上記のコードでは、コードの量を簡略化することもできます。c#は、入力を簡略化するためにusingを使用します。コンパイラーは自動的に変換してtry ...を最終的に行い、以下の記述を変更します。

using(SqlConnection conn = new SqlConnection())
{
      //何かをする;
}

2.3リソースの解放に関する注意点

A. Dispose()メソッドを呼び出すとリソースをすぐに解放できることを示します。同時に、Finalize()メソッドの実行を削除することで、パフォーマンスが向上します。

B. Dispose()メソッドへの明示的な呼び出しがない場合、ガベージコレクターは、デストラクターを介してアンマネージリソースを解放することもできます。ガベージコレクター自体は、マネージリソースをリサイクルする機能を備えているため、リソースの通常の解放を保証しますが、ガベージによってのみリサイクラーのリサイクルは、時間内に解放されない管理されていないリソースの無駄になります。

C. .NETでは、リソースを解放するためにデストラクタをできるだけ使用しないでください。デストラクタのないオブジェクトは、ガベージプロセッサによって1つのプロセスでメモリから削除されますが、デストラクタのあるオブジェクトは2回呼び出す必要があり、デストラクタは最初に呼び出され、オブジェクトは2回目に削除されます。さらに、大量のリソース解放コードがデストラクタに含まれているため、ガベージコレクタの効率が低下し、パフォーマンスに影響します。

D.アンマネージリソースを含むオブジェクトの場合、ガベージコレクターに依存するのではなく、Dispose()メソッドを呼び出してリソースを回収することをお勧めします。

E.デストラクタは、ガベージコレクタのみが呼び出すことができます。

F. Despose()メソッドは、クラスのユーザーのみが呼び出すことができます。

G. .NETでは、IDisposableインターフェイスを継承するすべてのクラスでusingステートメントを使用できるため、スコープを超えた後、システムは自動的にDispose()メソッドを呼び出します。
H. IDisposableインターフェイスとデストラクタを実装するリソースセーフクラス。システムによるリソースの手動解放とリソースの自動解放に二重の保険を提供します。

2.4ファイナライズと破棄について

(1)Finalizeは、アンマネージリソースのみを解放します。

(2)、Disposeは管理対象リソースと管理対象外リソースを解放します。

(3)FinalizeとDisposeを繰り返し呼び出しても問題ありません。

(4)FinalizeとDisposeは同じリソース解放戦略を共有するため、両者の間で競合は発生しません。

 

==========================【出典および参照】==================== =======

https://www.cnblogs.com/yubinfeng/p/4625833.html

https://www.cnblogs.com/yangecnu/archive/2013/04/30/3052652.html

https://www.2cto.com/kf/201007/52838.html

.NETプログラミングプロセスでは、メモリガベージコレクションの大部分はCLR(共通言語ランタイム)によって自動的に収集されますが、コードのリサイクルが必要なものも多数あります。管理対象と管理対象外の基本的な知識を習得すると、特定の状況によって引き起こされるプログラムの異常を効果的に回避できます。

1.管理および非管理

1.1管理されているものと管理されていないもの

マネージコードは、Visual Basic .NETおよびC#コンパイラによってコンパイルされたコードです。コンパイラーは、コードを中間言語(IL)にコンパイルします。コンピューターで直接実行できるマシンコードではありません。中間言語は、アセンブリと呼ばれるファイルにカプセル化されます。アセンブリには、作成したクラス、メソッド、プロパティ(セキュリティ要件など)を説明するすべてのメタデータが含まれます。このアセンブリを別のサーバーにコピーして展開できます。一般的に言えば、このコピーアクションは、展開プロセスにおける唯一の操作です。

マネージコードは、共通言語ランタイム(CLR)で実行されますこのランタイムライブラリは、実行中のコードにさまざまなサービスを提供します。一般的に、このランタイムライブラリは、アセンブリを読み込んで検証し、中間言語が正しいことを確認します。特定のメソッドが呼び出されると、ランタイムライブラリは特定のメソッドをローカルコンピューターの操作に適した機械コードにコンパイルし、次の呼び出しのためにコンパイルされた機械コードをキャッシュします(これはジャストインタイムコンパイルです)。アセンブリの実行中、ランタイムはセキュリティ、メモリ管理、スレッド管理などのさまざまなサービスを提供し続けます。このプログラムは、ランタイムで「ホスト」されます。Visual Basic .NETおよびC#では、マネージコードのみを生成できます。これらの言語でプログラムを作成する場合、生成されるコードはマネージコードです。

管理対象リソース:通常、CLR(共通言語ランタイム)によって制御されるメモリリソースを指し、これらのリソースはCLRによって管理されます。.netクラスライブラリのリソースと見なすことができます。

アンマネージリソース:CLRによって制御および管理されないリソース。

管理対象リソースの場合、GCはガベージコレクションを担当します。アンマネージリソースの場合、GCはアンマネージリソースのライフタイムを追跡できますが、解放する方法がわからないため、現時点では手動で解放する必要があります。

1.2どのリソースが管理されていませんか?

アンマネージコードは、Visual Basic 6、Visual C ++ 6など、Visual Studio .NET 2002のリリース前に作成されたコードです。最悪のことは、まだハードディスク上にあり、15年以上の歴史を持つ古いCコンパイラによって生成されたコードでさえ、アンマネージコードであることです。アンマネージコードはターゲットコンピューターの機械的コードに直接コンパイルされます。これらのコードは、コンパイル元のコンピューター、または同じプロセッサまたはほぼ同じプロセッサを搭載した他のコンピューターでのみ実行できます。アンマネージコードは、セキュリティやメモリ管理など、一部のランタイムが提供するサービスを利用できません。アンマネージコードがメモリ管理などのサービスを実行する必要がある場合は、オペレーティングシステムのインターフェイスを明示的に呼び出す必要があります。一般的には、Windows SDKが提供するAPIを呼び出して実現します。最近の状況では、アンマネージプログラムはCOMインターフェイスを介してオペレーティングシステムサービスを取得します。Visual Studioプラットフォームの他のプログラミング言語とは異なり、Visual C ++はアンマネージプログラムを作成できます。プロジェクトを作成し、名前がMFC、ATL、またはWin32で始まるプロジェクトタイプを選択すると、このプロジェクトはアンマネージプログラムを生成します。

要約すると、アンマネージコードは、共通言語ランタイム環境(CLR)の外部で実行され、オペレーティングシステムによって直接実行されるコードですアンマネージコードは、ガベージコレクション、型チェック、セキュリティサポートなどの独自のサービスを提供する必要があります。これは、共通言語ランタイムからこれらのサービスを取得するマネージコードとは異なります。

一般的に言えば、CLRによって制御および管理されないのはリソースです。

含む:ファイルストリーム、イメージグラフィック、データベース接続、ネットワーク接続、システムウィンドウハンドル、プリンターリソースなど。通常、このようなリソースはヒープ上に存在しません。オペレーティングシステムのリソースと見なすことができるAPIのセット。

原則:クラスがデータベース接続、ファイルハンドルなどのアンマネージリソースを使用する場合、これらのリソースを次のように解放する必要があります。

1.3マネージドコードの実行プロセス

  1. コンパイラを選択します。共通言語ランタイムが提供する利点を得るには、ランタイム用の1つ以上の言語コンパイラ(Visual Basic、C#、Visual C ++、JScript、または多くのサードパーティコンパイラ(Eiffel、Perlなど)を使用する必要があります。 COBOLコンパイラ)。ランタイムは多言語実行環境であるため、さまざまなデータ型と言語関数をサポートしています。使用する言語コンパイラは、最初に使用可能なランタイム関数を決定し、次にこれらの関数を使用してコードを設計します。コンパイラーは(ランタイムではなく)コードが使用する必要のある構文を確立します。コンポーネントが他の言語で記述されたコンポーネントで完全に使用可能でなければならない場合、コンポーネントのエクスポートタイプは、共通言語仕様(CLS)に含まれる言語機能のみを公開する必要があります。
  2. ソースコードをコンパイルしてMicrosoft Intermediate Language(MSIL)に変換し、必要なメタデータを生成します。
  3. 実行時に、リアルタイム(JIT)コンパイラはMSILをネイティブコードに変換します。このコンパイルプロセス中、コードは、MSILとメタデータをチェックしてコードがタイプセーフであると判断できるかどうかを確認する検証プロセスを実行する必要があります。
  4. コードの実行:共通言語ランタイムは、実行を可能にし、実行中に使用できるさまざまなサービスの構造を提供します。

2.アンマネージリソースを解放するにはどうすればよいですか?

.NETの場合、リソースを解放する標準的な方法は次のとおりです。

(1)IDisposableインターフェイスを継承します。

(2)Dispose()メソッドを実装します。このメソッドでは、マネージリソースとアンマネージリソースが解放され、オブジェクト自体がガベージコレクターから削除されます(ガベージコレクターはこのリソースをリサイクルしません)。

(3)クラスデストラクタ実装し、その中でアンマネージリソースを解放します。

 Dispose()メソッドのいくつかのパラメーターの説明:

A.パラメータがtrueの場合、すべてのリソースが解放され、ユーザーのみが呼び出すことができます

  パラメータがfalseの場合、ガベージコレクタによってのみ自動的に呼び出されるアンマネージリソースを解放することを意味します。

C.サブクラスに独自のアンマネージリソースがある場合、この関数をオーバーロードして、独自のアンマネージリソースリリースを追加できます。

D.ただし、この関数のオーバーロードでは、基本クラスのバージョンが呼び出され、基本クラスのリソースが正常に解放されるようにする必要があります。 

2.1 Disposeの実装方法

...書く時間があるとき

2.2リソース解放の例

2.2.1データベース接続の解放

(1)間違った練習:  

SqlConnection conn = new SqlConnection();
//何かをする;
conn.Dispose();

このコードでは、例外conn.Dispose()が時間内に実行に失敗すると、接続が時間内に閉じられなくなります。

(2)正しいアプローチ: 

コードをコピー
SqlConnection conn = new SqlConnection();
試す
{
    //何かをする;
}
最後に
{
    conn.Dispose();
}
コードをコピー

上記のコードでは、コードの量を簡略化することもできます。c#は、入力を簡略化するためにusingを使用します。コンパイラーは自動的に変換してtry ...を最終的に行い、以下の記述を変更します。

using(SqlConnection conn = new SqlConnection())
{
      //何かをする;
}

2.3リソースの解放に関する注意点

A. Dispose()メソッドを呼び出すとリソースをすぐに解放できることを示します。同時に、Finalize()メソッドの実行を削除することで、パフォーマンスが向上します。

B. Dispose()メソッドへの明示的な呼び出しがない場合、ガベージコレクターは、デストラクターを介してアンマネージリソースを解放することもできます。ガベージコレクター自体は、マネージリソースをリサイクルする機能を備えているため、リソースの通常の解放を保証しますが、ガベージによってのみリサイクラーのリサイクルは、時間内に解放されない管理されていないリソースの無駄になります。

C. .NETでは、リソースを解放するためにデストラクタをできるだけ使用しないでください。デストラクタのないオブジェクトは、ガベージプロセッサによって1つのプロセスでメモリから削除されますが、デストラクタのあるオブジェクトは2回呼び出す必要があり、デストラクタは最初に呼び出され、オブジェクトは2回目に削除されます。さらに、大量のリソース解放コードがデストラクタに含まれているため、ガベージコレクタの効率が低下し、パフォーマンスに影響します。

D.アンマネージリソースを含むオブジェクトの場合、ガベージコレクターに依存するのではなく、Dispose()メソッドを呼び出してリソースを回収することをお勧めします。

E.デストラクタは、ガベージコレクタのみが呼び出すことができます。

F. Despose()メソッドは、クラスのユーザーのみが呼び出すことができます。

G. .NETでは、IDisposableインターフェイスを継承するすべてのクラスでusingステートメントを使用できるため、スコープを超えた後、システムは自動的にDispose()メソッドを呼び出します。
H. IDisposableインターフェイスとデストラクタを実装するリソースセーフクラス。システムによるリソースの手動解放とリソースの自動解放に二重の保険を提供します。

2.4ファイナライズと破棄について

(1)Finalizeは、アンマネージリソースのみを解放します。

(2)、Disposeは管理対象リソースと管理対象外リソースを解放します。

(3)FinalizeとDisposeを繰り返し呼び出しても問題ありません。

(4)FinalizeとDisposeは同じリソース解放戦略を共有するため、両者の間で競合は発生しません。

 

==========================【出典および参照】==================== =======

https://www.cnblogs.com/yubinfeng/p/4625833.html

https://www.cnblogs.com/yangecnu/archive/2013/04/30/3052652.html

https://www.2cto.com/kf/201007/52838.html

おすすめ

転載: www.cnblogs.com/hanguoshun/p/12738758.html