希望能得到任何形式的帮助。
情景简述 -
服务器上有一个运行在COM+中的程序(使用C#编写)。这个COM的任务是接收一个文件名,多页tif文件的页面编号和分辨率,将其转换为gif文件图像。该COM通过代理从Web应用程序调用。网站获取转换后的图像,并以所请求的分辨率显示。对于打印,它会发出两个请求——第一个是显示分辨率,第二个则会以完整分辨率进行打印(使用window.print())。
问题 -
一段时间后,服务器会耗尽内存,无法在网站上显示图像。需要定期重新启动服务器。
错误
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 ---
我没有访问生产服务器的权限,但系统管理员发送的错误消息显示了"OutOfMemory"。
因此,假设存在内存泄漏并专注于它——根据我有限的处理此类情况的经验,我的发现如下:
- Perfmon - 我看到进程/私有字节和.Net CLR内存/堆中的字节数正在增加。因此,我认为这是托管内存泄漏。不过我不确定。
- CPU使用率 - 起始时为8%,最高达到了80%。后来降回并保持在3%-12%之间,除了几次回到75%-85%。不确定这里发生了什么。
我开始调试服务器COM以查看堆、gcroot等。
- 每次请求完成后,堆中计数递增的对象有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();
}