我正在开发一个.NET Windows服务,它创建了几个线程,然后使用这些线程将打印作业发送到打印机(每个打印机都有一个线程)。我有一些问题有时可以通过重新启动服务来解决。当服务运行一段时间后,也会出现一些问题。这让我怀疑可能存在内存泄漏。所以,有几个问题:
如果一个对象是在一个线程内创建的,它会收集一个对象,还是该对象会存在,直到该线程被停止/终止为止?
我可以使用哪些工具来监控Windows服务和我以编程方式启动的线程所使用的内存量?
答案 0 :(得分:3)
所有对象都是在线程内创建的。执行的每条指令都在一个线程中。在没有对它们进行实时引用之后,对象将在某些时刻被垃圾收集。对象不属于他们创建的线程。
为了监控服务,您可以使用具有大量计数器的perfmon
来进行垃圾收集。有关可能泄漏对象的位置的详细分析,您应该使用分析器。如果您的程序也作为非服务运行,则所有这些都可能变得更简单。 (您可能希望将其分成“启动器”部分,然后将其分离到可以从服务或控制台应用程序中使用的库。)
答案 1 :(得分:1)
答案 2 :(得分:0)
.NET垃圾收集器释放了不再“可访问”的对象所占用的内存。要发现哪些对象“可以访问”(因此不符合垃圾回收条件),GC会暂停所有线程,从一组“根”对象开始,并尝试遍历整个图形。未标记为可达的每个对象都成为垃圾收集的候选对象。在最初分配内存时,哪个线程处于活动状态没有区别;重要的是在垃圾收集的第一阶段你的对象不再可用。 “根”包括所有局部变量和方法参数(这些是每个服务线程的堆栈中的变量)和静态变量。
Microsoft有一个名为Debugging Tools for Windows的免费下载,其中包括windbg.exe。此工具可用于创建进程(私有)内存的转储。您可以这样调用它:windbg.exe -p <processID>
该工具(借助SOS扩展程序)允许您自己导航可到达的对象。如果您的问题在于可用的可管理对象过多,该工具应该能够提供帮助。