3
SqlConnection connection = new SqlConnection(FROM_CONFIGURATION) 
SqlCommand command = new SqlCommand("SomeSQL", connection); 
connection.Open(); 
command.ExecuteNonQuery(); 
command.Dispose(); 
connection.Dispose();

例外がスローされた場合にすべてのリソースが適切に破棄されるように、上記のコードに try/catch (または using) を含めることをお勧めします。

しかし、手作業で物を処分することを心配しなければならない場合、GC のポイントは何でしょう?! コーダーのためにこれを処理するためにGCはありませんか?

4

15 に答える 15

15

ここで他の人が言ったように、GC は非決定論的であるため、オブジェクトがいつ収集されるかはわかりません。明確にしたいのは、これはメモリの問題ではなく、システム リソース (開いているファイル、データベース接続) に問題があるということです。これは高価であり、できるだけ早くリリースする必要があります。Dispose を使用すると、接続を使用しなくなったことがわかっているときにそれを行うことができます。それらが時間内に解放されない場合、システムはそれらのリソースを使い果たす可能性があり、GC はそれを認識しません。そのため、手動で行う必要があります。

また、「using」ステートメントを使用すると、うまくいくことを付け加えたいと思います。

于 2008-10-21T19:46:49.707 に答える
7

ガベージ コレクションは、未使用のメモリを解放する処理を行います。

GC を拡張して他のリソースを解放することが問題となる理由はさまざまです。そのうちの 1 つは、ファイナライザー (オブジェクトがガベージ コレクションされるときに実行されるメソッド) は、ファイナライザーからの逆参照を強く制限しない限り、参照サイクルを収集できないようにすることです。

もう 1 つの理由は、ほとんどのリソースを何らかのタイムリーな方法で解放する必要があることです。これは、ガベージ コレクションに依存している場合には不可能です。

さらにもう 1 つの理由は、GC をメモリ管理に限定することです。これは、あらゆるアプリケーションの膨大な量のリソース管理と、重要でないリソース管理のほとんどすべてを処理するためです。他のリソースは通常、それらがどのようにリリースされるかを明示する追加のコードに値するほど興味深いものです。

もう 1 つの理由は、一部のアプリケーションでは、所有権のセマンティクスに対応するために行われるコピーの量が削減されるため、GC によってアプリケーションが高速化されることです。これは、他のリソースにとっては問題ではありません。

他の人は、このように何時間も続けることができます。

于 2008-10-21T19:48:51.120 に答える
6

しかし、手作業で物を処分することを心配しなければならない場合、GC のポイントは何でしょう?! コーダーのためにこれを処理するためにGCはありませんか?

問題は、GC がいつ実行されるかわからないことです。また、アプリケーションがメモリを圧迫しない場合は、まったく実行されない可能性があります。

于 2008-10-21T19:40:40.747 に答える
5

次のコードがあるとします。

class MonkeyGrabber : IDisposable {
   public MonkeyGrabber() { /* construction grabs a real, live monkey from the cage */
   public void Dispose() { Dispose(true); /* releases the monkey back into the cage */ }
   // the rest of the monkey grabbing is left as an exercise to grad student drones
}

class MonkeyMonitor {
    public void CheckMonkeys() {
        if (_monkeyPool.GettingTooRowdy()) {
            MonkeyGrabber grabber = new MonkeyGrabber();
            grabber.Spank();
        }
    }
}

現在、私の MonkeyMonitor はサルをチェックし、乱暴すぎる場合は、貴重なシステム リソースを取得します。つまり、システムに取り付けられた 1 つのサルをつかむ爪が、それを使用してサルをつかんで叩きます。処分しなかったので、モンキークローはまだ猿を抱きかかえており、休息ケージの上にぶら下がっています。残りのサルが乱暴を続けている場合、新しい MonkeyGrabber を作成することはできません。おっとっと。不自然な例ですが、要点はわかります。IDisposable を実装するオブジェクトは、タイムリーに解放する必要がある限られたリソースを保持する場合があります。GCは最終的に手放すかどうか。

さらに、一部のリソースはタイムリーにリリースする必要があります。アプリケーションが終了する前にアプリまたは GC のいずれかによって破棄されない場合、アプリがクラッシュする原因となる一連のクラスがあります。これは、それらの元のアンマネージド リソース マネージャーが、GC がそれに到達するまでに既になくなっているためです。 .

IDisposable の詳細

using はあなたの友達です- これまでのところRAIIに最も近いものです。

于 2008-10-21T19:55:57.080 に答える
4

IDisposable を実装するオブジェクトは、マネージ メモリではない構造へのリンクがあることを伝えようとしています。ガベージ コレクターは、効率を向上させるためにバッチで実行されます。ただし、これは、オブジェクトが破棄されるまでにしばらく時間がかかることを意味します。つまり、必要以上に長くリソースを保持することになり、パフォーマンス/信頼性/スケーラビリティに悪影響を及ぼす可能性があります。

于 2008-10-21T19:44:16.573 に答える
3

GC は時折実行され、メモリ管理を処理して、すべてを適切に整頓します。あなたが投稿したようなコードの断片を見ると、役に立たないと思うかもしれませんが、多くの場合、メモリ リークが大幅に減少し、心配できるため、多くの頭痛の種 (C/C++ の手動メモリ管理を考えてください) を節約できます。メモリの管理方法ではなく、アプリケーションの実行方法について。ガベージ コレクションは決定論的ではなく、すぐに実行されない可能性があるため、ファイル ハンドルとデータベース接続を破棄することは効率を高める方法です。また、これらのファイル ハンドルと開いているデータベース接続によってシステムのパフォーマンスが低下することは望ましくありません。ところで、あなたのコードは本当に醜いです。私は常に using ステートメントを提唱し、頻繁に次のような db コードを記述します。

using (SqlConnection connection = new SqlConnection(...))
using (SqlCommand command = connection.CreateCommand())
{
   ...
}

これは、実行がブロックを離れたときに、接続オブジェクトとコマンド オブジェクトがスコープ外になると、自動的に dispose を呼び出します。

于 2008-10-21T19:47:38.893 に答える
2

...GC はリソースを管理するためのものではありませんでした。メモリ割り当てを管理するように設計されています...データベース接続の特定のケースでは、メモリ以外のリソースを扱っています... (Scott Dorman)

OPは特定のプラットフォームでタグ付けしませんでしたが、ほとんどの回答は.net固有のものであり、GCは主にメモリリークを回避するためのものですが、using式などの拡張機能IDisposableは大いに役立ちます.

他のプラットフォームは、他のソリューションを提供します。たとえば、C++ には (組み込みの) ガベージ コレクションはありませんが、一部の形式の共有ポインターを使用してメモリ管理を支援することができ、RAII スタイルのコーディングは他の種類のリソースの管理に非常に役立ちます。

cPython では、2 つの異なるガベージ コレクション システムが使用されます。参照カウントの実装は、最後の参照が削除されるとすぐにデストラクタを呼び出します。一般的な「スタック」オブジェクトの場合、これは、C++ RAII オブジェクトの場合と同様に、すぐにクリーンアップされることを意味します。欠点は、参照サイクルがある場合、参照カウント コレクターがオブジェクトを破棄しないことです。その結果、Java および .NET コレクターのように機能する二次的な非決定論的ガベージ コレクターがあります。using ステートメントを持つ .NET と同様に、cPython は最も一般的なケースを処理しようとします。

したがって、OPに答えるために、非決定論的ガベージコレクションはメモリ管理を簡素化するのに役立ち、適時性が問題にならない限り他のリソースの処理にも使用でき、別のメカニズム(注意深いプログラミング、参照カウントGC、 using ステートメント、または実際の RAII オブジェクト) は、他のリソースをタイムリーに解放する必要がある場合に必要です。

于 2008-10-21T20:01:40.703 に答える
2

GC は最も効率的ではないため、リソースが使用されなくなるとすぐに実行されるとは限りません。そのため、ファイル I/O、DB 接続などの管理されていないリソースを扱っている場合は、それらのリソースを解放またはクリーンアップしてから、GC に処理を任せることがベスト プラクティスです。

そして、usingキーワードの使用を検討してください:

using (SqlConnection connection = new SqlConnection(FROM_CONFIGURATION))
using (SqlCommand command = new SqlCommand("SomeSQL", connection))
{
  connection.Open(); 
  command.ExecuteNonQuery(); 
  command.Dispose(); 
  connection.Dispose();
}

また、原則として、破棄できるものはすべてusingブロックにする必要があります。

于 2008-10-21T19:43:31.910 に答える
1

上記のコードは、取得したリソースを解放します (ただし、Dispose() メソッドを自分で呼び出す必要はないと思います。リソースを解放することは、ストリームなどを閉じることを意味します)。GC はメモリからオブジェクトを削除します (オブジェクトが使用していたメモリの割り当てを解除します) が、オブジェクトによってリソースが解放された後にのみ実行できます。

于 2008-10-21T19:40:09.063 に答える
1

これがどのように見えるかについてはよくわかりませんが、通常、ガベージコレクターがメモリを管理します。この接続には、オブジェクト メモリに加えて、サーバー リソースがあります。別のプロセスにあるデータベースは、接続を維持する必要があります。閉じると、それらがクリーンアップされます。

于 2008-10-21T19:41:18.967 に答える
1

あ、なるほど。メモリ管理とアンマネージ リソース管理を混同しました。明確にしてくれてありがとう!

于 2008-10-22T03:35:13.973 に答える
1

.NET のガベージ コレクター (GC) は、.NET 共通言語ランタイム (CLR) のコア部分であり、すべての .NET プログラミング言語で使用できます。GC はリソースを管理するためのものではありませんでした。メモリ割り当てを管理するように設計されており、ネイティブ .NET オブジェクトに直接割り当てられたメモリの管理に優れています。管理されていないメモリとオペレーティング システムが割り当てたメモリを処理するようには設計されていないため、これらのリソースを管理するのは開発者の責任になります。

データベース接続の特定のケースでは、メモリ以外のリソース、特に接続プール、可能な暗黙的なトランザクション スコープなどを扱っています。管理対象リソースが GC サイクルの発生を待機する間、すぐにリソースを解放します。

于 2008-10-21T19:47:51.870 に答える
0

GC はオブジェクトの破棄を処理しますが、破棄はすぐには行われない場合があります。オブジェクトを手動で破棄すると、メモリがより速く解放されます。

于 2008-10-21T19:41:24.130 に答える
0

DB 接続やファイル ハンドルなどの外部リソースを解放する場合、GC は制限されます。ただし、.NET の世界でメモリを割り当てる場合は、多くのありふれたメモリ管理タスクを処理します。

于 2008-10-21T19:42:59.480 に答える
0

上記は、ネイティブに割り当てられたメモリまたはリソースがハンドルとしてマネージド ワールドに移動する場合の例を示しています。このシナリオでは、マネージ ワールドがメモリを割り当てていないため、「自動整理」できません。メモリ/リソースは明示的に破棄するか、少なくともファイナライザー内で破棄する必要があります。

ただし、ほとんどの場合、特にほとんどの企業のコア目的 (ビジネス ロジック) にとって重要なコードについて話すときは、この種のことを心配する必要はなく、コードが少ないほど間違いが少なくなります。

于 2008-10-21T19:49:07.157 に答える