私のASP.NET MVC3アプリケーションは、Ninjectを使用してラッパーを介してサービスインスタンスをインスタンス化します。コントローラのコンストラクタにはIMyServiceパラメータがあり、アクションメソッドはmyService.SomeRoutine()を呼び出します。サービス(WCF)は、wsHttpBindingを使用してSSL経由でアクセスされます。メモリリーク - WCF例外
私はWCF(オブジェクトグラフ内で直列化または非直列化できる項目の最大数)で設定した最大値を超える非常に多くの結果を返す検索ルーチンを用意しています。このような状況が発生すると、サービスとクライアントの両方のアプリケーションプールが著しく増加し、依頼の最後を過ぎても十分に膨らんでいます。
結果の数を制限したり、送信されるデータの量を減らすためにDTOを使用することができます。つまり、私はメモリリークのように見えるものを修正したいと思います。
CLR Profilerを使用し、私は、ヒープの大部分は、以下で使用されていることがわかり:
- System.RunTime.IOThreadTimer.TimerManager
- System.RunTime.IOThreadTimer.TimerGroup
- System.RunTime .IOThreadTimer.TimerQueue
- System.ServiceModel.Security.SecuritySessionServerSettings
- System.ServiceModel.Channels.SecurityChannelListener
- System.ServiceModel.Channels.HttpsChannelListener
- System.ServiceModel.Channels.TextMessageEncoderFactory
- System.ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder
- System.Runtime.SynchronizedPool
- System.Runtime.SynchronizedPool.Entry []
- ... TextMessageEncoderFactory.TextMessageEncoder.TextBufferedMessageWriter
- System.Runtime.SynchronizedPool.GlobalPool
- System.ServiceModel.Channels.BufferManagerOutputStream
- System.Byte [] []
- System.Byte [](92%)
また、Iは、空のリストを返すために、検索ルーチンを変更する場合(ただし、NHibernateの情報はバックグラウンドでログに記録されますが、ロギングによって確認されます)、アプリケーションプールのサイズは変更されません。検索ルーチンが例外なく重要な結果を返す場合、アプリケーションプールサイズは変更されません。私は、オブジェクトのリストがシリアル化され、例外が発生したときにリークが発生すると考えています。
私は最新のNinjectにアップグレードし、log4netを使用して、サービスクライアントがその状態に応じてクローズまたはアボートされたことを確認しました。私が面白いと思ったのは、サービスラッパーがファイナライズされ、明示的に処理されていないということだけでした。
このシナリオでは、アプリケーションプールがメモリを解放していない理由を調べるのに問題があります。他に何を見ているべきですか?
更新日:ここにはバインディングがあります...
<wsHttpBinding>
<binding name="wsMyBinding" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:02:00" sendTimeout="00:02:00" bypassProxyOnLocal="false"
transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="999999" maxReceivedMessageSize="99999999"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="false"
allowCookies="false">
<readerQuotas maxDepth="90" maxStringContentLength="99999"
maxArrayLength="99999999" maxBytesPerRead="99999"
maxNameTableCharCount="16384" />
<reliableSession enabled="false" />
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
UPDATE#2:ここではNinjectは結合が、より多くの好奇心は、エラーメッセージです。私のラッパーは、MaxItemsInObjectGraphを正しく設定していないので、デフォルトを使用していました。私がこれを設定すると、漏れがなくなった。サービスがシリアル化されたデータをクライアントに送信し、クライアントがMaxItemsInObjectGraphを超えてクライアントを拒否すると、クライアントとサービスはシリアル化/非直列化データをメモリ内に保持していると考えられます。
Ninjectバインディング:
Bind<IMyService>().ToMethod(x =>
new ServiceWrapper<IMyService>("MyServiceEndpoint")
.Channel).InRequestScope();
エラーメッセージ:
のInnerExceptionメッセージは' オブジェクトグラフにシリアライズまたはデシリアライズすることができるアイテムの最大数である' ました65536 '
これは実際にメモリリークを修正するものではありませんので、誰かがアイデアを持っている場合、何が原因で発生しているのか不思議です。
ラッパーにはどのバインディングを使用しますか? –
@Remo:上記のバインディングを追加しました - ありがとう! – Mayo
申し訳ありませんが私は十分に明確ではなかった。私は、ラッパーの作成に使用されたNinject Bindingを意味しました。特にスコープは興味深い。 –