.NET Windows服务,线程和垃圾收集(可能的内存泄漏)

时间:2010-04-09 06:21:29

标签: .net multithreading service garbage-collection

我正在开发一个.NET Windows服务,它创建了几个线程,然后使用这些线程将打印作业发送到打印机(每个打印机都有一个线程)。我有一些问题有时可以通过重新启动服务来解决。当服务运行一段时间后,也会出现一些问题。这让我怀疑可能存在内存泄漏。所以,有几个问题:

如果一个对象是在一个线程内创建的,它会收集一个对象,还是该对象会存在,直到该线程被停止/终止为止?

我可以使用哪些工具来监控Windows服务和我以编程方式启动的线程所使用的内存量?

3 个答案:

答案 0 :(得分:3)

所有对象都是在线程内创建的。执行的每条指令都在一个线程中。在没有对它们进行实时引用之后,对象将在某些时刻被垃圾收集。对象不属于他们创建的线程。

为了监控服务,您可以使用具有大量计数器的perfmon来进行垃圾收集。有关可能泄漏对象的位置的详细分析,您应该使用分析器。如果您的程序作为非服务运行,则所有这些都可能变得更简单。 (您可能希望将其分成“启动器”部分,然后将其分离到可以从服务或控制台应用程序中使用的库。)

答案 1 :(得分:1)

答案 2 :(得分:0)

.NET垃圾收集器释放了不再“可访问”的对象所占用的内存。要发现哪些对象“可以访问”(因此不符合垃圾回收条件),GC会暂停所有线程,从一组“根”对象开始,并尝试遍历整个图形。未标记为可达的每个对象都成为垃圾收集的候选对象。在最初分配内存时,哪个线程处于活动状态没有区别;重要的是在垃圾收集的第一阶段你的对象不再可用。 “根”包括所有局部变量和方法参数(这些是每个服务线程的堆栈中的变量)和静态变量。

Microsoft有一个名为Debugging Tools for Windows的免费下载,其中包括windbg.exe。此工具可用于创建进程(私有)内存的转储。您可以这样调用它:windbg.exe -p <processID>

该工具(借助SOS扩展程序)允许您自己导航可到达的对象。如果您的问题在于可用的可管理对象过多,该工具应该能够提供帮助。