9

EWS Managed APIを使用して、指定された間隔の後に新しいメールメッセージをMS Exchangeにポーリングします。ポーリングコール(PullSubscription.GetEvents())が呼び出されるたびに、Microsoft APIはNetworkStreamを適切に処理できず、メモリがそれに比例して増加します。以前はdiscussed hereでしたが、決して解決されませんでした。 ANTS Profilerを使用して、どのオブジェクトがメモリ内で連続的に成長しているのかを特定し、問題を特定できました。参照できないオブジェクトのガベージコレクションを強制するには?

ここで問題が切り分けられました。私たちが参照していない外部APIで作成されたNetworkStreamを処分する方法はありますか? GC.Collect()はまだアクティブな参照があるので、GC.Collect()はそれを破棄していないようです。ダングリングリファレンスをクリーンアップするにはどうすればよいですか?バグのあるSDKを強制的にクリーンアップするために使用できるラッパーがありますか?

+0

私は疑問に思っています - 反射を介して参照を保持できますか? –

+0

孤立したNetworkStreamがライブラリ内にある場所を投稿してください。私はちょうどGetEventsMethodの周りを突き刺しましたが、NetworkStreamは見つかりませんでした。 –

+0

@HenningKrause私はDaren Thomasのアプローチを試しましたが、スキップするために選択したExchangeServiceおよびSubscriptionBaseクラスの内部について深い調査が必要になります。現在私はサルバトーレの#1を今のところ追ってきて、MSと一緒にチケットを開いた。私たちは次に何が起こるかを見ていきます... – SliverNinja

答えて

6

GCに参照オブジェクトのメモリを強制的に解放させる方法はありません。

まず、私はこのバグの助けを借りてマイクロソフト自身に連絡することを提案します。

第2に、「廃棄」またはメモリの解放について話していますか?彼らは2つの全く異なるものです。 (IDisposableパターン、ファイナライザ)。

第3に、これらのオブジェクトを参照しているオブジェクトを逆参照できますか?

第4に、リフレクターで問題を解決するコードを逆コンパイルし、参照されたオブジェクトを保持しているフィールドに到達する方法を理解し、コード内のリフレクトを使用してプライベートフィールドにアクセスすることができますそれらをnullにする。 非常に汚れたハックですが、他の方法がない場合は、私が考えることができる唯一のものです。あなたが他の方法で行くことができない場合にのみこれをしてください。

+0

フィールドが静的でない場合でも、4の汚れたハックが機能します。これは、「参照されない」べきではないオブジェクトがあると想定していますが、問題のあるオブジェクトを生きている状態に保つ(おそらくは間接的に)ものです。 – svick

+0

もちろん、この方法はすべての状況で機能しますが、他のオブジェクトを逆参照していないオブジェクトを間接参照することができれば、これを行うことができます。 –

0

最も簡単な方法は、SDKを独自のAppDomainにインターフェイスする部分を実行して、AppDomainをアンロードした後です。これにより、AppDomainに割り当てられたすべてのメモリが解放されます。

AppDomainと交換できるのはMarshalByRefというオブジェクトか、serilizableとマークされているため、プロジェクトに作業を追加する必要があります。

これにより、AppDomainが消費するメモリ量を監視することもできます。 AppDomainを作成してバグのあるSDKを実行し、メモリ消費の特別な制限に達するとアンロードできます。

関連する問題