【问题标题】:.NET Windows Service, threads and garbage collection (possible memory leaks).NET Windows 服务、线程和垃圾收集(可能的内存泄漏)
【发布时间】:2010-04-09 06:21:29
【问题描述】:

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

如果对象是在线程中创建的,垃圾收集器会收集它吗?还是在线程停止/终止之前对象会一直存在?

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

【问题讨论】:

  • 可能是打印机代码使用了非托管代码,这些代码被保留而不发布。如果您在单独的应用程序域中加载打印代码,您至少可以将其卸载以释放内存并防止重新启动服务。

标签: .net multithreading service garbage-collection


【解决方案1】:

所有对象都是在线程内创建的。曾经执行的每条指令都在一个线程内。在没有对它们的实时引用后,对象将在某个时候被垃圾收集。对象不“属于”创建它们的线程。

要监控服务,您可以使用perfmon,它有很多计数器用于垃圾收集等操作。要更详细地分析您可能在哪里泄漏对象,您应该使用分析器。如果您的程序可以作为非服务运行,那么所有这些都可能会变得更简单。 (你可能想把它分成一个“启动器”部分,然后是一个可以从服务或控制台应用程序中使用的库。)

【讨论】:

    【解决方案2】:

    【讨论】:

      【解决方案3】:

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

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

      该工具(在 SOS 扩展的帮助下)允许您自己导航可访问的对象。如果您的问题在于可访问的托管对象过多,该工具应该能够提供帮助。

      【讨论】:

        猜你喜欢
        • 2012-06-28
        • 1970-01-01
        • 2016-11-02
        • 2018-05-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-03
        • 2011-02-12
        相关资源
        最近更新 更多