冻结托管线程

时间:2012-02-17 11:08:25

标签: c# .net multithreading

我正在开发一个相当大的应用程序,负责进行实时运动跟踪和摄像机移动控制。它的任务是:

  • 动作跟踪(由本机模块完成,该模块解码来自网络摄像机的视频流,并提供大至1280x720像素的图像缓冲区,并通过回调将跟踪结果发送到托管应用程序)
  • 从移动/倾斜硬件接收定位反馈数据并向移动/倾斜硬件发送大约20次,以及从/向摄像机发送缩放命令
  • 显示包含实时可视化的图像数据
  • 编码和写入图像和会话数据
  • 视频的自动后处理由另一个进程完成

该应用程序使用.NET 4.0并具有WPF用户界面。

管理线程冻结

从一开始我们就不得不面对冻结500到1500毫秒的托管线程,这对于像这样的实时应用来说非常重要。

为了找出这些挂起的时间,我创建了一个线程,其唯一的任务就是始终保持100ms的睡眠状态。然后,我计算了睡眠真正花了多长时间,并确切地确定了摄像机运动停止的时间。它工作非常可靠,线程都同时挂起!

非托管线程不会冻结

虽然所有托管线程都冻结了非托管线程,但没有任何问题。我们通过独立于应用程序的托管部分编写的日志来检查。

分析

我试图找出现象可能会导致这种行为:

  • 当我们遇到这些问题时,整个机器会变慢:Windows的响应速度非常慢(例如,目录列表在Windows资源管理器和我的应用程序中都会挂起半分钟,或启动应用程序的时间非常长)
  • 我们同时读取和写入数千个文件(跟踪和后处理应用程序),也许这会过度充电窗口
  • GUI的响应变得非常慢
  • 该应用程序使用大约1.3GB的虚拟内存(根据Process.VirtualMemory64)/ 500MB的工作集内存(Process.WorkingSet64) - 是否可以将其中一些交换到硬盘上? (如何检查或解决?)
  • 当然如果我们终止Windows进程再次快速响应,但Windows需要一段时间才能正常响应

如何调查这一点的提示将受到高度赞赏。非常感谢你!

2 个答案:

答案 0 :(得分:1)

答案 1 :(得分:1)

我建议您在遇到性能问题时进行进程转储。您可以通过多种方式执行此操作(来自SysInternals的taskmgr.exe或procdump.exe)。进行完整的内存转储。

获得.dmp文件后,可以使用windbg(或Visual Studio 2010)进行分析。对于托管进程,您需要加载sos.dll扩展。

那里有很多很好的windbg资源,但这里有一些帮助我:

1)Tess Fernandez video(ASP.NET过程,但技术相同)

2)WinDbg cheatsheet

当您遇到问题时,内存分析将能够为您提供堆栈(!clrstack)并告诉您确切的罪魁祸首。