3

私のアプリには、数秒ごとに作成される大きなオブジェクトがあります。私はそれでいくつかの仕事をします、そしてそれから私はもうそれを必要としません。

タスクマネージャーで、オブジェクトへの参照がなくてもRAMサイズが大きくなり、収集する必要があることがわかりました。

IDisposableラムを実装した後、すぐにダウンします。

どうしてこれなの?私はしませんでしGC.Collectた。オブジェクトを解放して、GCにオブジェクトのファイナライザーを呼び出す必要がないことを伝えました。

編集:

IDisposableオブジェクトに使用するコードは次のとおりです。

public void Dispose()
{
  base.Dispose();
  Dispose(true);
  GC.SuppressFinalize();
}

private void Dispose(bool disposing)
{
  //here i release unmanaged resources
  if (disposing)
  {
    //here i release all managed resources
  }
}

~MyObject()
{
  Dispose(false);
}

私の大きなオブジェクトでは、myObject.Dispose();もう必要なくなった後に行います。

私の質問は、どのように実装するIDisposableか、またはGCが一般的にどのように機能するかについてではありませんでした。オブジェクトを自分で処分したり、GCに任せたりすると、どうして違いがあるのか​​知りたいだけです。

4

4 に答える 4

1

@Steven がコメントで指摘したように、 IDisposable は CLR が気にしないものです。これを実装することで、オブジェクトが不要になったときに Dispose メソッドを呼び出すように、オブジェクトの消費者に指示するだけです。メモリ管理に関しては、IDisposable2 などの独自のインターフェイスを作成して、同じ技術的効果を得ることができます。ただし、.net 開発者は、オブジェクトが不要になったときに idisposable.dispose を呼び出すことを知っておく必要があるため、これは愚かなことです。また、このインターフェイスには組み込み言語 (c#) のサポートがあります ({...} を使用)。

「IDisposable を実装しようとしたところ、RAM がすぐにダウンしました」と書いています。

重要なのは、あなたの「実装」が何をするかです。そこにあるコードは、アンマネージ コード、Windows リソースなどをクリーンアップする必要があります。

于 2012-07-06T09:27:42.223 に答える
0

IDisposable を使用するということは、不要になったリソースのすべてのクリーンアップ コードを配置する Dispose メソッドを実装していることを意味します。オブジェクトをマネージ ヒープに削除するわけではありません。GC は引き続きメモリを解放する役割を果たします。

于 2012-07-06T09:51:39.793 に答える
0

.NET では、メモリには通常のように 2 つの状態 (使用済みと未使用) はありませんが、実質的には 4: (A) ライブ オブジェクトによって使用される、(B) デッド オブジェクトによって使用される、(C) どのオブジェクトによっても使用されませんが、フレームワークおよび (D) は使用されません。

オブジェクトを作成すると、フレームワークは最初にカテゴリ (C) のメモリを使用しようとします。使用可能なメモリが十分に残っていない場合、OS にタイプ (D) の一部を要求し、それを次のように変換します。 (C) オブジェクトに使用します。

オブジェクトがスコープ外になると、(A) から (B) に移行し、次のガベージ ランで (B) から (C) または (D) に移行します。これは、内部構造 (メモリの断片化とその仲間を考えてください)、メモリのプレッシャー、および収集されたオブジェクトのタイプ (IDisposable とその仲間を考えてください) に大きく依存します。

あなたが達成したいのは、大きなオブジェクトが範囲外になった後、できるだけ早く、それが使用したメモリが (D) に移動することです。ここにいくつかのヒントがあります:

  • オブジェクトのサイズが 4K の倍数であることを確認してください。これにより、他のオブジェクトがオブジェクトとメモリ ページを共有する可能性がはるかに高くなるため、OS に簡単に戻すことができます。

  • オブジェクトの破棄を囲むブラケットを試してAddMemoryPressure()ください。ただし、副作用に注意してください。これは forcing に似てGC.Collect()いますが、あまり邪魔になりません: GC がすぐに収集するように示唆しますが、正確には今ではありません

  • 基本概念を再考してください。大きなオブジェクトはシングルトンですか (つまり、常に 1 つしか存在できません)。はいの場合は、一度割り当ててリサイクルすることを検討してください。これにより、アプリケーションの RAM 要件がより予測可能になり、実行中の醜い OOM 状況から救われる可能性があります。

于 2012-07-06T09:22:59.703 に答える
-2

IDisposable を実装してオブジェクトを破棄すると、そのオブジェクトはガベージ コレクションの対象としてマークされます。

ただし、いつ収集されるかを正確に予測することはできません。

于 2012-07-06T09:15:42.497 に答える