3

デバイスの 1 つを制御し、このデバイスからの信号に反応する C# のアプリケーションがあります。

基本的に、アプリケーションはスレッドを作成し、操作 (データベースへのアクセスなど) を処理し、このデバイスと通信します。

アプリケーションの実行中、オブジェクトを作成して解放します。これまでのところ、ガベージ コレクターにメモリの処理を任せています。干渉せずにGCに処理をさせることを強くお勧めします。

今私たちが直面している問題は、アプリケーションのプロセスが徐々に成長し、永遠に成長することです。例:

ここに画像の説明を入力

アプリケーションが成長しているときに「波」があるように見え、突然、アプリケーションがメモリを解放しますが、同時にメモリ リークが発生するようです。

いくつかのメモリ プロファイラーを使用してアプリケーションを調査しようとしていますが、ガベージ コレクターがどのように機能するかを深く理解したいと考えています。

皆さんは、GC に関する別の非常に深いドキュメントを知っていますか?

編集 :

アプリケーションの動作を示すスクリーンショットを次に示します。

非常に規則的なパターンで発生している「波」効果をはっきりと見ることができます。

補助的な質問:

GC コレクション 2 ヒープが非常に大きく、アプリケーションで使用される合計バイト数と同じパターンに従っていることがわかりました。私たちのオブジェクトのほとんどは、少なくとも 2 つのガベージ コレクション (たとえば、Singleton クラスなど) に耐えられるため、これはまったく正常なことだと思います...どう思いますか?

4

3 に答える 3

1

数年前に教えていたクラスについて調査しました。参考文献には LoH に関する情報は含まれていないと思いますが、どちらの方法でも共有する価値があると思いました (以下を参照)。さらに、ガベージ コレクターのせいにする前に、解放されていないオブジェクト参照を再度検索することをお勧めします。クラスファイナライザーにカウンターを実装するだけで、これらの大きなオブジェクトが予想どおりにドロップされていることを確認できます。

この問題に対する別の解決策は、大きなオブジェクトの割り当てを解除せず、代わりにプーリング戦略でそれらを再利用することです。私の傲慢さから、時間の経過とともに増加するアプリケーションのメモリ要件について時期尚早に GC を非難することになったことが何度もありましたが、これは多くの場合、不完全な実装の兆候ではありません。

GC リファレンス: http://blogs.msdn.com/b/clyon/archive/2007/03/12/new-in-orcas-part-3-gc-latency-modes.aspx http://msdn.microsoft. com/en-us/library/ee851764.aspx http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx http://blogs. msdn.com/b/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx

Eric Lippert のブログは、C# を詳細に理解する上で特に興味深いものです。

于 2012-10-01T12:56:05.290 に答える
1

あなたが説明する動作は、Large Object Heap (LOH) で作成されたオブジェクトの問題の典型です。ただし、後でメモリ消費量がいくらか低い値に戻るように見えるので、それが本当に LOH の問題であるかどうかを 2 回確認してください。

あなたは明らかにそれを認識していますが、LOH のオブジェクトのサイズには例外があるということはあまり明白ではありません。

ドキュメントで説明されているように、サイズが 85000 バイトを超えるオブジェクトは最終的に LOH になります。ただし、何らかの理由で (おそらく「最適化」)、1000 要素を超える double の配列も最終的にそこに配置されます。

double[999] smallArray = ...; // ends up in 'normal', Gen-0 heap
double[1001] bigArray = ...; // ends up in LOH

これらの配列は、メモリ不足の例外が発生するまで、より多くのメモリを必要とする断片化された LOH を引き起こす可能性があります。

一部のセンサー読み取り値を double の配列として受け取るアプリがあり、すべての配列の長さがわずかに異なるため、LOH デフラグが発生したため、これに悩まされました (これらは、非リアルタイム プロセスによってサンプリングされた、さまざまな周波数でのリアルタイム データの読み取り値でした)。この問題は、独自のバッファー プールを実装することで解決しました。

于 2012-10-01T12:03:19.653 に答える
0

ここに私の調査のいくつかの更新があります:

私たちのアプリケーションでは、さまざまなタスクを作成するために多くのスレッドを使用しています。これらのスレッドのいくつかは、より高い優先度を持っています。

1)同時実行の GC を使用しており、それを非同時実行に戻そうとしました。

劇的な改善が見られました:

  • ガベージ コレクターは頻繁に呼び出されており、より頻繁に呼び出されると、メモリの解放が大幅に改善されるようです。

これを説明するための良いスクリーンショットができ次第、スクリーンショットを投稿します。

MSDN で非常に優れた記事を見つけました。SOに関する興味深い質問も見つかりました。

次の Framework 4.5 では、GC 構成に 4 つの可能性が利用可能になります。

  1. ワークステーション - 非並行
  2. ワークステーション - コンカレント
  3. サーバー - 非同時
  4. サーバー - 同時

「サーバー - 非並行」と「サーバー - 並行」に切り替えて、パフォーマンスが向上するかどうかを確認します。

このスレッドは、私たちの調査結果で更新され続けます。

于 2012-10-05T12:07:59.023 に答える