アンマネージリソースとは正確には何ですか?


159

アンマネージリソースについて知りたい。誰か私に基本的なアイデアを教えてもらえますか?


また、IDisposableをの適切な使用のための幻想的な説明とパターンを与えるこのページを参照してください、とアンマネージリソースを取る方法口座に:stackoverflow.com/questions/538060/...
カイルバラン

回答:


177

マネージリソースとは、基本的にはガベージコレクターによって管理される「マネージメモリ」を意味します。管理対象オブジェクト(管理対象メモリを使用する)への参照がなくなると、ガベージコレクターは(最終的に)そのメモリを解放します。

アンマネージリソースは、ガベージコレクターが認識していないすべてのものです。例えば:

  • ファイルを開く
  • オープンなネットワーク接続
  • アンマネージメモリ
  • XNAの場合:頂点バッファー、インデックスバッファー、テクスチャなど

通常、それらを管理しているオブジェクトへのすべての参照を失う前に、それらのアンマネージリソースを解放する必要があります。Disposeそのためには、そのオブジェクトを呼び出すか、(C#では)using呼び出しDisposeを処理するステートメントを使用します。

Disposeアンマネージリソースを正しく無視すると、そのリソースを含むオブジェクトがガベージコレクションされたときにガベージコレクターが最終的に処理します(これは「ファイナライズ」です)。ただし、ガベージコレクターはアンマネージリソースを認識していないため、リソースを解放する必要があるかどうかを判断できません。そのため、プログラムのパフォーマンスが低下したり、リソースが完全に不足したりする可能性があります。

アンマネージリソースを処理するクラスを自分で実装する場合はDisposeFinalize正しく実装するかどうかはユーザー次第です。


7
オープンデータベース接続はどのカテゴリに属しますか?マネージド/アンマネージド?
Deviprasad Das 2010

8
+1他の回答は、ラップするアンマネージリソースの解放を内部で処理するマネージオブジェクト(たとえば、ファイルハンドル、GDI +ビットマップなど)でDisposeを呼び出すという重要なポイントを逃し、アンマネージリソースに直接アクセスする場合( PInvokeなど)、それを処理する必要があります。
Ian Mercer

2
@Dev:アンマネージド-GCがそれを認識しないため(架空のインマネージドメモリデータベースを使用していないと想定)。ただし、接続オブジェクト自体がアンマネージリソースを保持していない場合あります。おそらくデータベース接続はどこかで開いているファイルまたはネットワーク接続を使用していますが、別のオブジェクト(接続オブジェクト以外)がそのアンマネージリソースを処理している可能性があります(データベースライブラリが接続をキャッシュしている可能性があります)。ドキュメントを確認し、電話Disposeまたは使用を依頼する場所を確認してくださいusing
Andrew Russell

11
これに関する基本的なコメント/質問があります。オブジェクトをタイプだけで管理/非管理として関連付けることができますか。たとえば、文字列は管理され、DataSetは非管理です(そのため、Dispose()メソッドがあります)。 、データベース接続は管理されていない(破棄されているため)などです。つまり、 "Dispose()"メソッドがある場合、管理されていないのではないでしょうか。それに加えて、XmlDocumentオブジェクトは何でしょうか?おかげで
ガンダース

15
@gandersそれは良い経験則です。ただし、すべてのC#クラスインスタンスは管理対象オブジェクトであることに注意してください。クラスのインスタンスがアンマネージリソースを保持できる場合、そのクラスはを実装する必要がありますIDisposable。クラスは場合ない実装IDisposable、あなたがすべきであると、そのクラスのインスタンスを処分するusingDispose()、あなたは彼らと一緒に行われたとき。これに基づいて、あなたの逆は成り立ちます:クラスがを実装する場合、IDisposableそれはおそらく内部的にアンマネージリソースを保持します。
アンドリューラッセル

56

一部のユーザーは、オープンファイル、db接続、割り当てられたメモリ、ビットマップ、ファイルストリームなどを管理対象リソース間でランク付けし、他のユーザーは非管理対象リソース間でランク付けします。管理されているか、管理されていないのですか?

私の意見では、応答はより複雑です:.NETでファイルを開くとき、おそらくいくつかの組み込みの.NETクラスSystem.IO.File、FileStreamなどを使用します。通常の.NETクラスであるため、管理されます。しかし、それは実際にファイルを開く「汚れた作業」(Win32 dllを使用してオペレーティングシステムと通信し、低レベルの関数またはアセンブラー命令を呼び出す)を行うラッパーです。そして、これは、.NETが知らない、管理されていないものです。ただし、アセンブラー命令を使用して自分でファイルを開き、.NETファイル関数をバイパスすることができます。次に、ハンドルと開いているファイルはアンマネージリソースです。

DBと同じ:DBアセンブリを使用する場合、DbConnectionなどのクラスがあり、それらは.NETに認識され、管理されます。しかし、それらは管理されていない「ダーティーワーク」をラップします(サーバーにメモリを割り当て、それとの接続を確立します...)。このラッパークラスを使用せず、自分でいくつかのネットワークソケットを開き、いくつかのコマンドを使用して独自の奇妙なデータベースと通信する場合、管理されません。

これらのラッパークラス(File、DbConnectionなど)は管理されますが、ラッパーを使用せずに自分で「汚い作業」を行う場合は、内部と同様にアンマネージリソースを使用します。したがって、これらのラッパーはDispose / Finalizeパターンを実装します。ラッパーが不要になったときにプログラマーがアンマネージリソースを解放し、ラッパーがガベージコレクションされたときに解放するのは、プログラマーの責任です。ラッパーはガベージコレクターによって正しくガベージコレクションされますが、内部のアンマネージリソースはDispose / Finalizeパターンを使用して収集されます。

組み込みの.NETまたはサードパーティのラッパークラスを使用せず、クラスのアセンブラー命令などでファイルを開く場合、これらの開いているファイルは管理されず、破棄/ファイナライズパターンを実装する必要があります。そうしないと、メモリリーク、永久にロックされたリソースなどが使用されなくなった場合(ファイル操作が完了した場合)や、アプリケーションが終了した後でも発生します。

しかし、これらのラッパーを使用するときもあなたの責任です。dispose / finaliseを実装する(それらはIDisposableを実装していることを認識している)場合は、dispose / finaliseパターンも実装し、これらのラッパーをDisposeするか、アンマネージリソースを解放する信号を送信します。そうしないと、リソースは一定の時間解放されてから解放されますが、すぐに解放しても問題ありません(ファイルをすぐに閉じて、数分/時間ランダムに開いたままブロックしないでください)。したがって、クラスのDisposeメソッドで、使用するすべてのラッパーのDisposeメソッドを呼び出します。


1
追加の明快さについての良いものunmanaged vs managed resources
今名付けられてはならない彼。

あなたの答えのためのTHX。実際にDisposeを呼び出すことをお勧めするクラスはどれですか。
BKSpurgeon 2016

2
これは簡単です。使用する各クラスで、IDisposableインターフェイスを実装しているかどうかを確認する必要があります。はいの場合、1つのメソッド(ファイルを開く、テキストを保存する、ファイルを閉じるなど)でこのようなクラスを使用すると、Disposeを自動的に呼び出すusing(){}パターンを使用できます。そのようなクラスをより多くのメソッドで使用する場合(例:クラスにファイルが含まれ、コンストラクターでファイルが開かれ、いくつかのメソッドでログが追加されます...)、クラスによってIDisposableインターフェイスを実装し、Dispose / Finalizeパターンを実装する必要がありますそして、そのクラスのオブジェクトを適切に破棄します。
Martas、2016

1
「...いくつかの組み込み.NETクラスSystem.IO.File、FileStreamなど。通常の.NETクラスなので、管理されます。」これに関しては、これは誤りであり、誤解を招くものです。彼らは管理されいません。それらが管理されている場合、これらのクラスを割り当てて、ガベージコレクターがすべてのリソースの割り当て解除を決定論的な方法で完全に処理することを期待できます。ただし、ガベージコレクターはクラスの割り当てを解除せず、潜在的に非常に長い間ファイナライズしないため、ファイルハンドルとアンマネージリソースが必要以上に長くロックおよび保持されることになります。
AaronLS 2016

1
@AaronLSはコメントの中で「FileStream」についてアンマネージドと呼びましたが、実際にはそうではありませんが、内部ではアンマネージドリソースを使用してその仕事を行っています。マネージドワールドでは、Microsoftはパターンを破棄します。マネージコードは、アンマネージリソースを使用しないという意味ではありません。ただし、Microsoftは、これらのタイプのオブジェクトにIDisposableを実装するという点で優れています。これは、IDisposableを実装しているという事実によって証明されています。その証拠に関しては、それを管理対象オブジェクトと見なす必要があります。
Malik Khalil、

12

アンマネージリソースは、.NETランタイム(CLR)(別名.NET以外のコード)の外部で実行されるリソースです。たとえば、Win32 APIでのDLLの呼び出しや、C ++で記述された.dllの呼び出しです。


6

「管理されていないリソース」は物ではなく責任です。オブジェクトがアンマネージリソースを所有している場合、つまり、(1)クリーンアップされていない場合に問題を引き起こす可能性のある方法でオブジェクトの外部にあるエンティティが操作されており、(2)オブジェクトにそのようなクリーンアップを実行するために必要な情報があり、責任があるそれを行うため。

多くの種類のアンマネージリソースは、さまざまな種類のオペレーティングシステムエンティティ(ファイル、GDIハンドル、割り当てられたメモリブロックなど)に非常に強く関連付けられていますが、単一の種類のエンティティが、それらの責任以外にすべてのエンティティによって共有されることはありません。掃除。通常、オブジェクトにクリーンアップを実行する責任がある場合、オブジェクトには、それが担当するすべてのクリーンアップを実行するように指示するDisposeメソッドがあります。

場合によっては、オブジェクトは、誰もが最初にDisposeを呼び出さずに破棄される可能性を考慮に入れています。GCにより、オブジェクトは(Finalizeと呼ばれるルーチンを呼び出すことにより)破棄されたという通知を要求でき、オブジェクトはこの通知を使用して、自分でクリーンアップを実行できます。

「管理されたリソース」や「管理されていないリソース」などの用語は、残念ながら別の人が別のことを意味するために使用しています。率直に言って、オブジェクトに関して、クリーンアップの責任がない、Disposeが呼び出された場合にのみ処理されるクリーンアップの責任がある、またはDisposeで処理する必要があるが、また、ファイナライズによって処理されます。


5

マネージリソースとアンマネージリソースの基本的な違いは、ガベージコレクターがすべてのマネージリソースについて知っていることです。ある時点で、GCが発生し、マネージオブジェクトに関連付けられたすべてのメモリとリソースをクリーンアップします。GCは、ファイル、ストリーム、ハンドルなどのアンマネージリソースを認識しないため、コードで明示的にクリーンアップしないと、メモリリークとリソースのロックが発生します。

ここから盗まれ。投稿全体を自由にお読みください。


2

.NETマネージヒープでメモリが割り当てられるリソースは、マネージリソースです。CLRはこの種のメモリを完全に認識しており、孤立しないようにあらゆることを行います。それ以外は管理されません。たとえば、COMとの相互運用により、プロセスのメモリ空間にオブジェクトが作成される場合がありますが、CLRはそれを処理しません。この場合、管理対象の境界を越えて呼び出しを行う管理対象オブジェクトは、それを超えるものに対する責任を負う必要があります。


0

まず、VB6またはC ++プログラム(非Dotnetアプリケーション)がどのように実行されていたかを理解しましょう。コンピュータは機械レベルのコードしか理解しないことはわかっています。マシンレベルのコードは、ネイティブコードまたはバイナリコードとも呼ばれます。したがって、VB6またはC ++プログラムを実行すると、それぞれの言語コンパイラがそれぞれの言語ソースコードをネイティブコードにコンパイルします。ネイティブコードは、基礎となるオペレーティングシステムとハードウェアで理解できます。

ネイティブコード(アンマネージコード)は、それが生成されるオペレーティングシステムに固有(ネイティブ)です。このコンパイルされたネイティブコードを取得して別のオペレーティングシステムで実行しようとすると、失敗します。したがって、このスタイルのプログラム実行の問題は、あるプラットフォームから別のプラットフォームに移植できないことです。

.Netプログラムがどのように実行されるかを理解しましょう。dotnetを使用して、さまざまなタイプのアプリケーションを作成できます。.NETアプリケーションの一般的なタイプには、Web、Windows、コンソール、モバイルアプリケーションなどがあります。アプリケーションのタイプに関係なく、.NETアプリケーションを実行すると、次のことが起こります。

  1. .NETアプリケーションは中間言語(IL)にコンパイルされます。ILは、Common Intermediate Language(CIL)およびMicrosoft Intermediate Language(MSIL)とも呼ばれます。.NETアプリケーションと非.NETアプリケーションの両方がアセンブリを生成します。アセンブリの拡張子は.DLLまたは.EXEです。たとえば、Windowsまたはコンソールアプリケーションをコンパイルすると、.EXEが取得されます。Webまたはクラスライブラリプロジェクトをコンパイルすると、.DLLが取得されます。.NETアセンブリとNON .NETアセンブリの違いは、DOTNETアセンブリは中間言語形式であり、NON DOTNETアセンブリはネイティブコード形式であるということです。

  2. 非DOTNETアプリケーションは、オペレーティングシステム上で直接実行できます。DOTNETアプリケーションは、共通言語ランタイム(CLR)と呼ばれる仮想環境上で実行されます。CLRには、Just In-Time Compiler(JIT)と呼ばれるコンポーネントが含まれています。これは、中間言語を、基になるオペレーティングシステムが理解できるネイティブコードに変換します。

したがって、.NETでは、アプリケーションの実行は2つのステップで構成されます。1。言語コンパイラ、ソースコードを中間言語(IL)にコンパイルします。2。CLRのJITコンパイラが変換し、ILをネイティブコードに変換して、基になるオペレーティングシステムで実行できるようにします。 。

.NETアセンブリはネイティブコードではなくIntermedaite言語形式であるため、.NETアセンブリは、ターゲットプラットフォームに共通言語ランタイム(CLR)がある限り、どのプラットフォームにも移植できます。ターゲットプラットフォームのCLRは、Intermedaite言語を、基になるオペレーティングシステムが理解できるネイティブコードに変換します。中間言語は、マネージコードとも呼ばれます。これは、CLRがその中で実行されるコードを管理するためです。たとえば、VB6プログラムでは、開発者はオブジェクトが消費するメモリの割り当てを解除する必要があります。プログラマがメモリの割り当てを解除するのを忘れた場合、メモリ不足の例外を検出することが困難になる可能性があります。一方、.NETプログラマは、オブジェクトが消費するメモリの割り当てを解除する必要はありません。自動メモリ管理は、グラベッジコレクションとも呼ばれ、CLRによって提供されます。別に、ガベージコレクションには、CLRによって提供される他のいくつかの利点があります。これについては、後のセッションで説明します。CLRは中間言語を管理および実行しているため、IL(IL)はマネージコードとも呼ばれます。

.NETは、C#、VB、J#、C ++などのさまざまなプログラミング言語をサポートしています。C#、VB、およびJ#はマネージコード(IL)のみを生成できますが、C ++はマネージコード(IL)とアンマネージコード(ネイティブコード)の両方を生成できます。

プログラムを閉じると、ネイティブコードはどこにも永続的に保存されません。ネイティブコードは破棄されます。プログラムを再度実行すると、ネイティブコードが再度生成されます。

.NETプログラムは、Javaプログラムの実行に似ています。JavaにはバイトコードとJVM(Java仮想マシン)があり、.NETのように中間言語とCLR(共通言語ランタイム)があります。

これはこのリンクから提供されます-彼は素晴らしい講師です。 http://csharp-video-tutorials.blogspot.in/2012/07/net-program-execution-part-1.html

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.