2009-02-26 45 views
10

高メモリ割り当て負荷のアプリケーションが2番目の世代のコレクションを100秒ごとに実行するシナリオが発生しましたか?100秒ごとにガベージコレクション

8〜16 GBの物理メモリを持つ64ビットサーバーを使用しています。

アプリケーションには、実際にアプリケーションで使用されているため、キャッシュに格納されているデータは数GBのデータがあり、そこから消去することはできません。さらに、処理中にGEN 0オブジェクトを割り当てる多くの要求を受け取ります。

私にとって奇妙なのは、GEN 2コレクションが時計のように100秒かけて行ったことです。私はそれが予測しにくいと思っていた

+3

これ以上のGC制御が必要な場合は、おそらくC#やVB.netなどの管理言語を使用すべきではありません。 これ以上のGCを作成していないし、既に.netに入っているものはありません。多くは試みました。すべてが失敗しました。 = P – Tony

+0

独自のガベージコレクタを作成するときは、自分のニーズに合わせて自由にカスタマイズすることができます。これは、.NETフレームワークの開発者が直面している問題よりもはるかに単純な問題になることがあります。その1つの特定の点以外は、私はトニーと概ね同意します。 –

答えて

25

多くのオブジェクトを使用し、多くのオブジェクトを使用している場合、はい:GCがビジー状態になる... gen-2に当たると、あなたのように聞こえる中/長寿命オブジェクトのロットがあります。

私は、メモリ使用量がかなり安定していると仮定していますか?上記のはのような何らかの擬似リークを示している可能性があります(静的イベントなどで多すぎるオブジェクトを保持している可能性があります)。

どのくらいのメモリを使用していますか?あなたはx64とたくさんの記憶を考えていただけますか?別の方法として、3GBスイッチ(x86)でもう少しバイトを購入しますか?

+0

しかし、なぜ「第二世代のコレクションを100秒ごとに実行したか」というのは、GCのタイミングを予測可能なものにしているのでしょうか? –

+1

メモリを使用する方法の偶然である可能性があります。つまり、致命的な状態になったり、GCを実行したり、毎回同じような量をリリースしたりします(同様の処理を長時間行っている場合は一般的です)。あるいは、それをGCに組み込むこともできます。私たちにはわからないと思っています... –

+2

サーバGCモードには時間ベースのヒューリスティックはありません。割り振り速度と生存オブジェクトを反映するように動的に調整されています。 – mfawzymkh

1

私はこれが.netのためであると仮定します。

GCは、そのアルゴリズムに基づいているときに収集します。収集するガベージコレクタを提案することはできますが、実際には何もしません。

GC.Collect()を使用して、ゴミを収集できるかどうかGCに問い合わせることができます。ただし、実際にメモリから項目を削除することはできません。

注:参照が正しくクリアされていることを確認してください。イベントのアンフックを意味する、オブジェクト間の参照のクリア。これにより、収集対象オブジェクトのGCがスコープ内に存在しなくなります。

4

メモリの使用は、プロセスとシステムの両方で非常に一貫している必要があります。ガベージコレクションは、これらのイベントのいずれかによってトリガされます。

  • ジェネレーション0の予算は
  • GC.Collect()と呼ばれているがいっぱいです
  • CLRがメモリに
  • のAppDomainのシャットダウン
  • CLRシャットダウン
  • を解放したい

あなたのケースの可能性の高い候補者は、おそらく定期的な収集(つまり、割り当てによる)または時間指定されたCollect()です。

編集:割り当てについて明確にする。通常のオブジェクトの割り当ては、常に世代0で発生します(例外は85000バイト以上のラージオブジェクトで、大きなオブジェクトヒープに割り当てられます)。インスタンスは、コレクションに残っている場合にのみ、世代1および2に移動されます。第1世代と第2世代には直接配分はありません。

また、世代0/1コレクションが十分なメモリーを解放しない場合(またはフル収集が明示的に要求された場合)に、世代2コレクション(フルコレクトとも呼ばれます)が実行されます。

+0

GC.Collectは使用せず、シャットダウンは実行されません。 – MichaelT

8

デュアルコアCPUを実行している場合は、app/web.configでGCServer = "true"を設定してみてください。

私のケースでは、元のGCの約10%を占めており、アプリケーションは非常にスムーズです。

4

多くのオブジェクトを生成している可能性があります。若いヒープに一度に収まるか、メモリリークが発生している可能性があります。

同時に生き生きとしなければならない多くのオブジェクトを集中的に作成している場合は、若いセクションがあふれている可能性があり、オブジェクトの一部を古い世代にコピーする必要があります。これにより、古いヒープがいっぱいになるほど、フルコレクションが頻繁に強制されます。 Sun JVMのように若いヒープを要求する方法がない限り、この場合は少数のオブジェクトを割り当てる方法を見つける必要があるでしょう。

実際にオブジェクトをどこかに保存すると(古いオブジェクトが所有するリストなど)、論理的なリークが発生します。一般的に、あなたは若いものを参照する古いオブジェクトを望んでいません。これは若いオブジェクトを昇格させる傾向があり、GCアルゴリズムは一般的に最適化されていません。また、オブジェクトが存続可能なスコープを大幅に短縮する場合(通常は余計ですが)、参照をクリアすることを検討することをお勧めします。

例外的に、メモリの使用量が異常に高い場合は、できることはほとんどありません。長時間実行しているプログラムでは、最終的にGCingを行う必要があります。一度に必要なメモリ量が増えると、それだけ頻繁になります。

+0

私にとって非常に奇妙に見えるのは、GCコレクションの100秒の洞穴です。 – MichaelT

2

私はあなたも.NETを使用していると仮定しています。あなたが使っているツールはわかりませんが、私はRed GateのAntsプロファイラの大ファンです。私は職場で使っています。どのオブジェクトがホッギングリソースであるかを識別できます。絞り込んだら、うまくいけば、問題のコードを見つけ出し、リソースを適切に解放することができます。

可能であれば、コードを確認してDispose()を呼び出していることを確認してください。

どうすればいいのか教えてください。

5

時計のように発生する第2世代のコレクションは、GC.Collectメソッドが時計のように呼び出されているか、割り当てが時計のようなものであることを示唆します。

ガベージコレクションで見られるランダム性は、割り当てやGC.Collectの呼び出しが本当にランダムでない限り起こりそうにありません。

サーバーアプリケーションの負荷が高く、処理中に新しいオブジェクトを作成した場合、オブジェクトプールなどを使用して、処理中に新しく作成できるオブジェクトの数を減らすために、コードのリファクタリングを真剣に検討します。

オブジェクトプールはプール内のオブジェクトをプールに戻すとすぐに再利用できるという点でほとんどのガベージコレクタと異なり、ガベージコレクタはオブジェクトを保持する前のメモリブロックの前にコレクションを実行する必要があります別のオブジェクトとして再び使用できます。

1

サーバーで実行しているので、マルチコアマシンでもあると想定しています。この場合、デフォルトでServer GCフレーバーが得られるので、設定ファイルに何も設定する必要はありません。

Gen2コレクションを100秒ごとに取得しているということは、割り当てパターンとオブジェクトのライフタイムパターンの要因です。あなたの割り当てパターンが一致している場合 、あなたはパフォーマンスモニタの下にカウンターPERFの.Net CLRメモリの下で見ることで、この動作を確認することができ、一貫性のあるGCのを取得します

あなたは次のメトリックを追跡する必要があります

  1. Gen0コレクション

  2. のGen 1つのコレクション

  3. のGen 2つのコレクション

  4. 割り当てられたバイト/秒
  5. すべてのヒープのバイト数。

あなたは最後のメトリックが増加し、ジグソーパズルのように動いて見えるはず、Gen2のコレクションでは、再び減少蹴り、そしてサイクルが繰り返されます。

これを回避するには、

  • を確認する必要がありますあなたは、プールでは?これは、すべて一緒にGCをリクエスト間でオブジェクトを避けることができますことができます。
  • そうでない場合は、リクエストごとに割り当てるオブジェクトの数を減らすことはできますか?

これが役に立ちます。 おかげ

+0

コメントは、サーバーモードがマルチコア環境ではデフォルトであり、http:// msdnではサポートされていません。 microsoft.com/en-us/library/ms229357.aspx。これらは、マシン上にいくつのコアがあるかにかかわらず、設定が常にfalseであることを示します。 – Slaggg

0

私が引き起こしているのか理解していないが、このような「クロックワーク」サイクルには、何もない現実のシステムを参照してくださいすることは非常に稀であり、「100秒ごとに第二世代の収集を行いました」。

メモリ負荷が高く、多くのオブジェクトを使用している場合、はい:GCがビジー状態になる場合があります.GEN-2に当たっていると、中/長寿命のオブジェクトがぶら下がっている...あなたはおそらくより多くのオブジェクトを生成しています。若いヒープに一度に収まるか、メモリリークがあります。

あなたには漏れがないと仮定すると、memory profilerでチェックしましたか?また、不要なゴミをたくさん作っていないと仮定しています(例:ループの内部にstring1 + = string2)。

私はかもしれない助けて2つのことを考えることができます。

リクエスト(スレッド)Asp.netプロセスの数を同時に制限することで、ライブオブジェクトの数を制限し、単一のリクエストの処理速度を上げることができます。 (多くのスレッドコンタクトスイッチを取得していますか?)

オブジェクトをAsp.netキャッシュおよび/またはAsp.netセッションに格納する場合。 Asp.netセッションサーバー、サードパーティ製セッションサーバー、memcache、またはMicrosoftから最近公開されたキャッシュサーバー(Velocity)など、このキャッシュ情報にアウトプロセスストアを使用することができます。必要なときにデータベースからデータを読み直すだけで、それを長期間のオブジェクトに格納するほうが良いかもしれません。

上記に失敗した場合、どのくらいのメモリを使用していますか?あなたはx64とたくさんの記憶を考えていただけますか?またはWebファーム..

0

ガベージコレクタが頻繁に呼び出されていることは、必ずしも大きな問題ではありません。しかし、あなたが最適にメモリを処理していないというフラグかもしれません(たとえば、方法に)。

ガベージコレクションは非決定的でなければなりません。つまり、重要なタスクがいくつか実行されているにもかかわらず、スレッドが(100秒ごとなどの)いくつかの合流点でスリープしている場合は、ガベージコレクタがその時点で収集する機会を得ることは妥当です。おそらく、多かれ少なかれ定期的な間隔で割り振りのピークが発生し、ガベージコレクタが使用されて未使用のメモリを取り出すために消費される可能性があります。

あなたのアプリケーションのメモリ消費をプロファイリングすることを強くお勧めします。

0

巨大なオブジェクトを100秒ごとに作成するのはあなたのアプリケーションだけなので、GCはその作業を強制されますか?

0

この100秒の周波数も見たことがありますが、すべてのプロダクション設定では発生しませんが、ローカルでも他の設定でも見ました。

+0

最終的に私はそれを解決しました。明らかに、サーバーGCを使用していたのは、サーバーGCに切り替えた後でも、GC2は呼び出されませんでした。どうやら並行GCには、1秒間に割り当てられるメモリの量を調べるという仮定があります。そして、それが特定の値よりも高い場合、gen 2 GCを100秒ごとに呼び出します – MichaelT

関連する問題