我有一个运行在Windows Server 2008上的C#编写的.NET 4 Windows服务,当使用PerfMon监视时,每小时会消耗2500个句柄。 "Handle Count"计数器不断上升。
使用ProcExp选择“Show Unnamed Handles and Mappings”选项查看句柄时,列出了数千个Event和Semaphore句柄。大多数似乎没有命名。我查看了源代码,并没有明确使用AutoResetEvent或ManualResetEvent。
Private Bytes计数器上升和下降。我还没有观察该进程超过几个小时,但会让它在夜间保持监控状态。
该服务在远程服务器上运行,因此无法直接附加调试器,可能必须转储进程并使用WinDBG或类似工具进行分析。
是否可能定位其中一个句柄并找出它指向什么和/或谁“拥有”它?如果可以,如何操作?
作为回应评论,以下是服务的摘要:
- 托管一些WCF服务 - 托管Quartz.NET调度程序的实例 - 托管工作项队列(quartz作业将工作项推入队列而不是自己长时间运行) - 托管工作项执行程序(工作项在定时器上出队并在Quartz之外执行) - 托管自定义缓存管理器(执行大量ADO.NET工作)
使用ProcExp选择“Show Unnamed Handles and Mappings”选项查看句柄时,列出了数千个Event和Semaphore句柄。大多数似乎没有命名。我查看了源代码,并没有明确使用AutoResetEvent或ManualResetEvent。
Private Bytes计数器上升和下降。我还没有观察该进程超过几个小时,但会让它在夜间保持监控状态。
该服务在远程服务器上运行,因此无法直接附加调试器,可能必须转储进程并使用WinDBG或类似工具进行分析。
是否可能定位其中一个句柄并找出它指向什么和/或谁“拥有”它?如果可以,如何操作?
作为回应评论,以下是服务的摘要:
- 托管一些WCF服务 - 托管Quartz.NET调度程序的实例 - 托管工作项队列(quartz作业将工作项推入队列而不是自己长时间运行) - 托管工作项执行程序(工作项在定时器上出队并在Quartz之外执行) - 托管自定义缓存管理器(执行大量ADO.NET工作)
IDisposable
接口的类型,都使用using
块进行实现。 - John Saunders