如何在C# Windows服务中解决句柄泄漏问题

5
我有一个运行在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工作)

听起来有点棘手。你的服务是做什么用的?人们可能会认为它使用了一些API,在后台进行一些未受控制的操作。也许,如果你提到你使用了哪些库,这将会唤起某个人的记忆。否则,恐怕你会得到像“确保调用.Dispose()”这样的回答。 - agent-j
你的服务器是否使用了非托管代码、并发集合或长轮询技术? - adontz
感谢您迄今为止的评论。请查看更新后的描述。 - IanT8
1
确保对于每个实现了 IDisposable 接口的类型,都使用 using 块进行实现。 - John Saunders
1个回答

1

故障排除背后的基本概念是隔离。隔离指的是进程和状态。

首先,您需要在您控制的环境中重现问题。如果在开发环境中设置某些服务需要太长时间,请考虑模拟它们。

一旦您控制了环境,就可以开始通过模拟或存根来削减执行的代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接