2016-04-11 36 views
5

私はインタラクティブなチャートを作成するプログラムに取り組んでいます。ただし、プログラムのレンダリングレイヤーが無効になっていても、次の問題が発生します。C#、なぜGCは毎秒何回も動作していますか?

Visual Studio 2015診断ツールによれば、GCは1秒間に約4回連続して実行され、アプリケーションのパフォーマンスが120fpsから15fpsに低下します。

予期しない割り当てが予想されるメモリスナップショットをいくつか取りましたが、スナップショットによれば、問題が発生しても数秒ごとにSystem.Internal.HandleCollector + HandleTypeの割り当てとコレクションが1〜は発生していません。

私が気づいたいくつかの他のもの:

これは、複数のマシンで起こる
  • これは、デバッガが接続されているかどうかに関係なく発生します。
  • アプリケーションのCPU時間の大部分は、clr.dllにあります。
  • スナップショットに観測可能な割り当てがない場合でも、各GCの実行理由は「スモールオブジェクトヒープ アロケーション」としてリストされています。

この時点で私は困惑しています。誰かがこれを見るか、どこでデバッグを開始すべきか知っていますか?

+0

あなたはグラフを生成するために何を使用していますか? GDI +?あなたはデータの変更や絶え間なくグラフィックを更新していますか? –

+0

私たちはSharpDX経由でDirectXを使用します。グラフは一度生成され、ユーザーの入力に基づいて変更され、フレームごとに描画されます。しかし、レンダリングレイヤーが完全に削除されても、この問題は引き続き発生します。 –

+0

Visual Studioに割り当てがないときに割り当てのためにGCをどのようにデバッグするのですか? "明確な問題文"を持たず、 "他の読者には役に立たない" –

答えて

0

GCと呼ばれる場所のコードを確認する必要があります。通常、1秒間に4回以下の速度で走行します。デバッガまたはプロファイラを、GCが呼び出された場所を見つけるための問題を持つインスタンスにアタッチします。多分それは第三者の図書館にあります。またはあなたがチェックすると思わなかったコード。これであなたのapp.configを変更し、実行

<configuration> 
    <runtime> 
     <gcServer enabled="true"/> 
    </runtime> 
</configuration> 
GCについて

さらに興味深いの詳細を作るために

+0

プロファイラに組み込まれているのは、それがGCであることをどのように決定したかです。 GCは決してコードから呼び出されません。私たちが使用する唯一のサードパーティライブラリはレンダリング用であり、レンダリングが無効になっている場合でも問題が発生します。 –

2
+0

問題は実行中のGCの実行ではなく、実行中のGCのパフォーマンスではないので、問題を隠蔽していないのでしょうか? –

+0

この設定は、GCが動作しているときにスレッドを停止する方法と方法を変更します。この特定の設定エントリは、ガベージコレクションを遅らせるよう指示します。だから、あなたはたくさんの記憶を持ち、あなたのアプリは単にメモリを使うと期待しています。メモリの割り当ては.NETで高速です。使用されていないメモリの収集が遅い。 GCよりもレポートを生成するのに十分なメモリがある場合は、良い瞬間を待つでしょう。 試して、パフォーマンスが向上するかどうかを確認してください。 –

2

あるの際に1ガベージコレクションが発生

https://msdn.microsoft.com/en-us/library/ee787088(v=vs.110).aspxから以下の条件が成り立つ:

システムh低い物理メモリとして。

管理されたヒープ上の割り当てられたオブジェクトによって使用されるメモリは、許容可能なしきい値を超えています。このしきい値は、プロセスの実行中に継続的に調整されます。

GC.Collectメソッドが呼び出されます。ほとんどの場合、このメソッドを呼び出す必要はありません。ガーベッジコレクタは継続的に実行されるためです。このメソッドは、主に固有の状況とテストに使用されます。

おそらく、上記の3つの条件のいずれかを満たしています。あなたのアプリケーションはたくさんのメモリを使用しているようですので、ガベージコレクションはいくつかのオブジェクトをクリーンアップしてメモリを解放しようとしています。

GC.Collect()があなたのコードのどこかにあり、ガベージコレクタが再び実行される可能性があります。

Hereはガベージコレクションに関するトラブルシューティングのガイドラインです。 1つのセクションは、特にあなたが持っている問題に関連しているようです。 「問題:ガーベッジ・コレクション中のCPU使用率が高すぎます」と表示されている部分では、次のように表示されます。

ガベージ・コレクション中はCPU使用率が高くなります。ガベージコレクションでかなりの処理時間が費やされた場合、コレクションの数が多すぎるか、コレクションが長時間持続しています。管理されたヒープ上のオブジェクトの割り当て率が高くなると、ガベージコレクションが頻繁に発生します。割当率を下げると、ガベージコレクションの頻度が減ります。

割り振り速度は、割り当てバイト/秒のパフォーマンスカウンターを使用して監視できます。詳細については、「.NET Frameworkのパフォーマンスカウンタ」を参照してください。

コレクションの期間は、主に、割り当て後も存続するオブジェクトの数の要素です。ガベージコレクタは、多くのオブジェクトが残っている場合は、大量のメモリを通過する必要があります。生存者を圧縮する作業には時間がかかります。コレクション中に処理されたオブジェクトの数を確認するには、指定された世代のガベージコレクションの最後にデバッガでブレークポイントを設定します。

+0

GC.GetTotalMemory()によれば、問題が発生している間に10MBのメモリが使用されています。 GC.Collect()は手動では呼び出されません。そして物理的な記憶がたくさんあります。 –

+0

GC.Collectをコード内のどこにでも置くことはありませんか?私はこれも私の答えに貼り付けます。 – Tophandour

+0

これはあなたの答えです。それは条件#3です。 –

関連する問題