ここで何か助けていただければ幸いです。
シナリオについての簡単な説明 -
サーバー上で実行されている COM+ があります (C# で記述)。この COM のタスクは、ファイル名、複数ページの tiff ファイルのページ番号、および解像度を取得して、gif ファイル イメージに変換することです。この COM は、プロキシを使用して Web アプリケーションから呼び出されます。Web サイトは変換された画像を取得し、要求された解像度で表示します。印刷の場合 - 2 つの要求を行います - 1 つ目はディスプレイ解像度、2 つ目はフル解像度 (window.print() を使用して印刷されます) です。
問題 -
しばらくすると、サーバーのメモリが不足し、画像が Web サイトに表示されなくなります。サーバーは定期的に再起動する必要があります。
エラー
EventType clr20r3, P1 imageCOM.exe, P2 1.0.0.0, P3 4fd65854, P4 prod.web.imaging, P5 1.0.0.0, P6 4fd65853, P7 1a, P8 21, P9 system.outofmemoryexception, P10 NIL.
Here is the error(s) on the web server (these continuously appear every minute) ….
System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it
at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.InternalConnect(EndPoint remoteEP)
at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Int32 timeout, Exception& exception)
--- End of inner exception stack trace ---
実稼働サーバーにアクセスできませんが、sysadmin から送信されたエラーは OutOfMemory を示しています。
したがって、メモリリークを想定してそれに焦点を当てる-これまでのところ、この種の状況を処理した経験が限られている私の発見-
- Perfmon - プロセス/プライベート バイトが増加していることがわかります。また、.Net CLR メモリ/ヒープ内のバイト数も増加しています。したがって、マネージドメモリリークだと思います。よくわかりませんが。
- CPU 使用率 - 8% から始まり、最初だけ 80% まで上がりました。75% から 85% に戻った数回を除いて、それは低下し、3% から 12% の間にとどまりました。ここで何が起こっているのかわかりません。
サーバーCOMのデバッグを開始して、ヒープ、gcrootなどを調べました。
- リクエストが行われるたびにカウントがヒープ内で増加するための 2 つのオブジェクトがあります。1 つのオブジェクトは、画像データを保持するオブジェクトです。2 番目のオブジェクトは、オブジェクト 1 (画像) が一定時間後に期限切れになったときにキャッシュから削除するためのイベント ハンドラーです。
- メソッド呼び出しを見ると、両方のオブジェクトが同じメソッドにつながっています。
- コード実装の賢明な - 要求された画像がキャッシュされています (特定の数まで) - パフォーマンス向上のためであることは理解できます。おそらくこれが、箇条書き 1 で述べたようにオブジェクトへの参照がヒープ内で増加している理由です。
非常にあいまいな説明をしたことは承知していますが、サーバー上の実際の問題を検出するには、なんらかの手がかりが必要です。
編集:画像オブジェクトは次のように破棄されました
Bitmap retVal;
using (MemoryStream buffer = new MemoryStream(doc.FileData, 0, doc.DocumentSize, false, false))
{
using (Bitmap original = new Bitmap(buffer))
{
//select the page to convert and
//perform scaling - full resolution or the requested resolution.
}
}
using (MemoryStream buffer = new MemoryStream())
{
retVal.Save(buffer, ImageFormat.Gif);
retVal.Dispose();
return buffer.GetBuffer();
}