2011-06-13 37 views
3

コンソールアプリケーションでホストされているWCFサービスがあります。 WCFの営業契約に電話するにはChannelFactoryがあります。WCFシリアル化とキャッシング

問題:私は値を返す操作を呼び出すたびに、返される値はシリアル化されたときにサービスによってどこかにキャッシュされているようです。

Windows 7のタスクマネージャを使用してサービスメモリの使用状況をチェックしています。何も返さない操作を呼び出すと、メモリは増加しませんが、データを返す操作を呼び出すとメモリが増加し、データがクライアントに返された後であっても。

私の推測では、これはシリアル化キャッシングの問題ですか?

+1

メモリプロファイリングを実行して、どのオブジェクトがメモリに残っているかを確認してください。明示的なキャッシュまたは静的変数を使用してデータを保持していますか? – oleksii

答えて

2

メモリは、GCが実行されるまで増加し続けている可能性があります。これは、データがクライアントに返されるタイミングに対応しません。

サービスメソッドにブレークポイントやロギングを追加して、各リクエストでメソッドが呼び出されていることを確認しましたか?私はWCFが単独でキャッシュを行うとは思わない。少なくとも、私はそれを使っている私のアプリケーションでそれをやったことはありませんでした。


編集:ガベージコレクタが実行されるまで

メモリが使用中のままになります。あなたのプロセスにまだヒープに十分な空き領域がある場合、GCが実行される理由はありません。

  • システムは低い物理メモリを有している:MSDNによれば

    : 次のいずれかの条件が真である場合http://msdn.microsoft.com/en-us/library/ee787088.aspx#conditions_for_a_garbage_collection

    ガベージコレクションが発生します。

  • 管理対象ヒープ上の割り当てられたオブジェクトによって使用されるメモリ は許容可能なしきい値を超えています。 これは、 許容メモリ使用量のしきい値が、マネージヒープ上で を超えていたことを意味します。この スレッシュホールドは、プロセスが実行されているので、継続的に調整されます( )。

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

あなたがヒープ内のオブジェクトを割り当てている可能性が高いですが、GCを実行する理由を見ていないので、彼らはGC'dされていない(ヒープ世代のオープンスペースがまだある、なしそれをクリアする時間を費やす理由)。

ただし、WCF呼び出しを何度も繰り返して、最終的にメモリ不足例外が発生した場合は、実際にどこかに保持されている参照に問題があることを示しています。その場合、メモリプロファイラを使用して、何が保持されているかを判断します。


編集#2:

も参照してくださいこのスレッド:C# Thread not releasing memory

+0

はい、あなたが言ったことをしました。このメソッドは各要求に対して呼び出されています。メモリが増えて決して解放されないたびに! – scatman

+0

ああ、おそらく私はあなたの質問を誤解しました。返信がキャッシュされていてメソッドが再実行されていないかのように、同じ応答がクライアントに繰り返し送信されているということを意味していたと思いました。私は答えを編集します... – CodingWithSpike

+0

オブジェクトはまだ使用されているので、操作でコレクションを呼び出すことはできません。 –

3

ガベージコレクタがまだ実行されていないように聞こえ、メモリが解放されなかったためです。さらに、コンソールアプリケーションでWCFサービスをホストする場合、GCはワークステーションモードで実行されます。このような場合は効果が低くなります。

+0

GCはいつ実行されますか?スタックオーバーフローの例外があり、GCが実行されませんでした。とにかく私は手動でメモリを解放できますか?またはGCを呼び出しますか? – scatman

+1

@scatman - StackOverflow例外がある場合は、他の問題があります。これは通常、ある種の再帰が完了していないことを示します。 'public void MethodA(){MethodB();} } public void MethodB(){MethodA();} } 'これらの関数の1つを呼び出すと、無限ループが発生し、呼び出しスタックが深すぎると最終的なStackOverflowExceptionが発生します。 – CodingWithSpike

+0

@scatman - ここに記載されているように、 'System.GC.Collect()'を呼び出すことによってGCを実行するよう手動で指示することができます:http://msdn.microsoft.com/en-us/library/system.gc.collect.aspxしかし、おそらくあなたのStackOverflowExceptionを助けることはありません。オブジェクト参照がガベージコレクションを妨げているかどうか判断するのに役立ちます。 – CodingWithSpike

1

収集/作成されているかのオブジェクトを確認するには、このようなツールを使用します。 http://memprofiler.com/

私はいないだろうGCが各呼び出しの後に実行されていないとあまり心配しないでください。これはあまり効率的ではありません。.NETフレームワークがオブジェクトが十分に古いものであると判断した時点でガベージコレクタが実行されます。メモリが不足し始めると、これはより頻繁に発生します。

関連する問題