【问题标题】:View/Diagnose logical .NET threads in memory dump using Visual Studio debugger使用 Visual Studio 调试器查看/诊断内存转储中的逻辑 .NET 线程
【发布时间】:2014-06-19 18:37:27
【问题描述】:

我有一个报告大量逻辑线程的服务。来自 PerfMon:

.NET CLR LocksAndThreads -> # of current logical threads: 663
.NET CLR LocksAndThreads -> # of current physical threads: 659
Process -> Thread Count: 15

这太高了,所以我捕获了一个内存转储(通过 sysinternals procdump.exe)并从 Visual Studio 中打开它(混合调试)。加载完所有内容后,我查看了线程窗口,它只显示了 15 个操作系统线程,而不是 .net 物理或 .net 逻辑。该服务本身是一个托管 4 个 WCF 服务 (System.ServiceModel.ServiceHost) 的 Windows 服务。

如何找出这些线程是什么,以便修复代码并摆脱它们? 如何让 Visual Studio 识别和显示逻辑线程? 是 Visual Studio 的问题,还是转储本身的问题?

【问题讨论】:

  • 如果您使用标准的 CLR 主机,那么您在逻辑线程和物理线程之间拥有 1 对 1 的映射。要获得更多帮助,您必须提供有关您的服务主机的更多信息。
  • 这是不可能的。可能是您创建小型转储的确切时间错误。
  • @HansPassant 到底什么是不可能的?我正在从实时提要中直接从 perfmon 读取值。这些值一直在上升(虽然缓慢),并且现在已经超过 16 小时不低于 400。几分钟前我又进行了一次内存转储,Visual Studio 中列出的线程与 Processes -> Thread Count 中的计数相匹配。
  • 我已经设法在 WinDbg 中加载转储并通过 !threads 命令列出线程。它列出了 ThreadCount:696 和 DeadThread:687。大多数线程的异常列被列为“线程池完成端口”。我不确定这意味着什么 - 仍在研究中
  • 请您回答一下自己的问题好吗?我认为社区对如何解决/调查问题进行简短描述会很棒。

标签: c# .net multithreading visual-studio-2010 visual-studio


【解决方案1】:

首先,您需要获取内存转储。有多种方法可以做到这一点。我发现的最简单的一个是 procdump.exe,它是 SysInternals 的一部分,随文档 here 提供。

接下来,您需要下载并安装 WinDbg 并让 SOS 正常工作(SOS 是让您查看 .net 托管进程的模块)。有关设置的更多信息,请访问here。如果您从服务器获取转储(如我的情况),那么 .net 版本可能会略有偏差,并且 SOS 将无法正确处理转储文件。如果发生这种情况,您需要按照this 评论将一些相关文件从源 .net 版本复制到您的 windbg 安装中。

一切都设置好并加载转储后,运行命令:

!threads

这应该会给你一个 .net 逻辑线程的列表。另外值得注意的是,在线程列表之前,它会给你一个摘要。对于这个问题很重要,DeadThread 非常高(600+)。这表明线程已经完成,但是它们所持有的内存(堆栈)无法释放。

在我的具体情况下,我发现挂起的线程是来自 WCF 线程池的线程,它们无法 GC,因为其他线程持有对它的引用。我将其他线程更改为在不再需要父线程时将其清空,这样就可以正确地进行 GC。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-11
    • 1970-01-01
    • 2013-11-08
    相关资源
    最近更新 更多