我有一个客户端/服务器应用程序。 服务器组件以“远程”方式运行,使用WCF(二进制格式化程序,会话对象)。
如果我启动服务器组件并启动客户端,服务器完成的第一个任务需时<0.5秒钟。
如果我使用VS调试器附加并启动客户端,则该任务需要高达20秒钟才能完成。
没有代码更改-没有条件编译更改。无论服务器组件编译并在32位、64位下运行,是否使用VS托管过程,没有使用VS托管过程还是任何这些事情的组合,情况都是相同的。
可能很重要:如果我使用VS.NET profiler(采样模式),则应用程序的运行速度与未附加调试器的速度一样快。所以我不能通过这种方式诊断它。刚才检查了,插装模式也运行得很快。并发分析模式也是如此。
关键数据:
- 应用程序使用相当多的多线程(标准线程池中有40个线程)。创建线程发生得很快,而且不是慢点。有很多锁、
WaitHandle
和Monitor
模式 - 应用程序不会引发任何异常。
- 应用程序不会创建控制台输出。
- 应用程序完全由托管代码组成。
- 应用程序将一些磁盘文件映射到MemoryMappedFile:1x750MB和12x8MB以及一些较小的文件
测量性能:
- 在这两种情况下,CPU使用率很低;当调试器附加时,CPU保持在<1%
- 在这两种情况下,内存使用率很低;可能为50或60MB
- 有大量页面故障(参考MMF),但是当附加调试器时,它们发生得更慢
无论客户端如何运行,都会看到性能差异。唯一更改的变量是通过“启动调试”运行的服务器组件与从资源管理器启动的组件有所不同。
我的想法:
- WCF在调试时很慢吗?
- MemoryMappedFiles在调试时很慢吗?
- 使用40个线程- 调试缓慢?也许监视器/锁通知调试器?线程调度变得奇怪/上下文切换非常不频繁?
- 宇宙背景辐射授予VS智慧和残酷的幽默感
所以,我的问题是:
- 为什么会出现这种情况?
- 如果第一个问题未知,则如何诊断/找出原因?