在负载很重的情况下,我们的应用程序正在使一个强大的服务器达到100%的CPU使用率.读取进程转储,查看线程,其中一些是10分钟.在使用时,他们都没有给我任何见解!CLRStack.
!失控给了我:
0:030> !runaway
User Mode Time
Thread Time
53:2e804 0 days 0:10:04.703
30:31894 0 days 0:07:51.593
33:47100 0 days 0:07:24.890
42:11e54 0 days 0:06:45.875
35:35e18 0 days 0:06:07.578
41:54464 0 days 0:05:49.796
47:57700 0 days 0:05:45.000
44:3c2d4 0 days 0:05:44.265
32:3898c 0 days 0:05:43.593
50:54894 0 days 0:05:41.968
51:5bc58 0 days 0:05:40.921
43:14af4 0 days 0:05:40.734
48:35074 0 days 0:05:40.406
...
Run Code Online (Sandbox Code Playgroud)
在其中一个线程上调用!DumpStack,我得到:
0000001ab442f900 00007ff9ef4c1148 KERNELBASE!WaitForSingleObjectEx+0x94, calling ntdll!NtWaitForSingleObject
0000001ab442f980 00007ff9e920beb2 clr!SVR::gc_heap::compute_new_dynamic_data+0x17b, calling clr!SVR::gc_heap::desired_new_allocation
0000001ab442f9a0 00007ff9e90591eb clr!CLREventWaitHelper2+0x38, calling kernel32!WaitForSingleObjectEx
0000001ab442f9b0 00007ff9e90e0d2c …
Run Code Online (Sandbox Code Playgroud) 我无法弄清楚命令行开关和参数的正确组合以提供给XPerf.exe以使其加载WPF ETW提供程序(Microsoft-Windows-WPF?a42c77db-874f-422e-9b44-6d89fe2bd3e5?E13B77A8-14B6-11DE -8069-001B212B5009}?)并监听特定事件(WClientInputMessage).
任何人都可以对这应该如何看待?文件的分散碎片(包括http://windowsclient.net/wpf/white-papers/event-tracing-wpf.aspx)和神秘的"xperf -help start"文本似乎是任何知识的荒原.
我们正在尝试了解Windows CPU Scheduler如何工作以优化我们的应用程序,以实现最大可能的基础架构/实际工作比率.在xperf中有一些我们不理解的东西,并且想要让社区了解真正发生的事情.当我们得到一些服务器"缓慢"或"无响应"的报告时,我们最初开始调查这些问题.
背景资料
我们有一台运行我们的中间件基础架构的Windows 2012 R2 Server,其规格如下.
我们发现有30%的CPU浪费在内核上,所以我们开始深入挖掘.
上面的服务器运行"主机"~500个进程(作为windows服务),这些"主机"进程中的每一个都有一个内部while循环,延迟〜250毫秒(yuck!),并且每个"主机"进程可能有〜 1..2执行实际工作的"子"进程.
虽然在迭代之间具有250毫秒延迟的无限循环,但"主机"应用程序执行的实际有用工作可能仅每10..15秒出现一次.所以浪费了很多周期来进行不必要的循环.
我们知道,"主机"应用程序的设计至少可以说是次优的,适用于我们的场景.应用程序将更改为基于事件的模型,该模型不需要循环,因此我们期望CPU利用率图中的"内核"时间显着减少.
然而,当我们调查这个问题时,我们已经做了一些xperf分析,它提出了几个关于Windows CPU Scheduler的一般性问题,我们无法找到任何明确/简明的解释.
我们不明白的是什么
以下是其中一个xperf会话的屏幕截图.
您可以从"CPU使用率(精确度)"中看到
有15毫秒的时间片,其中大部分未充分利用.这些切片的利用率约为35-40%.因此,我认为这反过来意味着CPU大约在35%到40%的时间内被利用,但系统的性能(假设通过系统周围的随意修改可观察到)实际上是缓慢的.
有了这个,我们就有了这个"神秘的"30%内核时间成本,由任务管理器CPU利用率图判断.
有些CPU明显用于整个15 ms及更高的分片.
问题
就多处理器系统上的Windows CPU调度而言:
是否可以使用ETW获取所有进程和系统的内存统计信息?内存统计我的意思是:例如,Commited bytes,private bytes,paged pool,working set,...
我找不到任何关于使用xperf获取和查看内存统计信息的信息.它总是关于CPU,磁盘,网络.
有人可能会使用性能计数器来获取这类信息,但如何在一个图表中以图形方式覆盖统计信息(如何关联/同步时间戳)?
我正在捕获 ADO.Net 诊断 ETW,如SQL Server 2008 中的数据访问跟踪中所述。设置有效,生成了一个 ETL 文件,如果我使用tracerpt ,我可以看到 ADO.Net 跟踪:
System.Data, TextA, 0, 0, 0, 0, 17, 0, 0x0000000000000000, 0x000007D0, 0x00003A64, 1, , , {00000000-0000-0000-0000-000000000000}, , 131485096603462277, 450, 2400, 2, "enter_01 <prov.DbConnectionHelper.CreateDbCommand|API> 1# "
System.Data, TextA, 0, 0, 0, 0, 17, 0, 0x0000000000000000, 0x000007D0, 0x00003A64, 1, , , {00000000-0000-0000-0000-000000000000}, , 131485096603469806, 450, 2400, 2, "<sc.SqlCommand.set_Connection|API> 1#, 1# "
System.Data, TextA, 0, 0, 0, 0, 17, 0, 0x0000000000000000, 0x000007D0, 0x00003A64, 1, , , {00000000-0000-0000-0000-000000000000}, , 131485096603469816, 450, …
Run Code Online (Sandbox Code Playgroud) 我为CLR提供者记录了ETW事件:
xperf -start clr -on e13c0d23-ccbc-4e12-931b-d9cc2eee27e4 -f clr.etl
...
xperf -stop clr
Run Code Online (Sandbox Code Playgroud)
然后在wpa.exe中打开clr.etl并看到大量的"通用事件".但似乎wpa不显示MSDN中描述的一些数据
我能看到的与此类似:
Process Unknown
Id 1
Opcode Name
Task Name
Provider Name e13c0d23-ccbc-4e12-931b-d9cc2eee27e4
Time 0,071731589s
Selection Duration 0,416407863s
Start Time 0,002151869s
End Time 0,418559732s
Data Points 1
Table Data Point Selection
Cpu 0
ThreadId 50 440
Sum of Count 1 23
Time (s) 0,071846769
Run Code Online (Sandbox Code Playgroud)
像这样的厕所是GCStart_V1
事件,但我找不到例如田地Reason
是否有可能在wpa中看到通用事件数据?
WPA版本 - 10.0.10586.212
我已经从Windows SDK安装了Xperf性能分析器,并使用以下命令捕获了文档中描述的跟踪:
xperf -on SysProf -stackwalk profile
Run Code Online (Sandbox Code Playgroud)
但是,堆栈跟踪不包含任何callstack数据.
我的平台是Vista 64b.在64b Windows上捕获callstacks是否需要任何特殊设置或技巧?
我最近已经熟悉了perfmon和xperf.Perfmon使用性能计数器,xperf使用ETW(Windows的事件跟踪).Perfmon具有提供数据的对象,而xperf使用"提供者"组.作为这个领域的新手,我问是否有人可以告诉我,perfmon使用的性能计数器是否真的基于与xperf使用的ETW事件相同的内容,如果是这样,你能否清楚地建立连接.如果它们不是基于相同的东西,你能解释它们是如何不同的吗?
我有两个问题:
我发现一个博客条目说DisablePagingExecutive
应该在使用时设置xperf
:
http://blogs.msdn.com/b/pigscanfly/archive/2009/08/06/stack-walking-in-xperf.aspx
禁用分页执行程序
为了使跟踪在64位Windows上运行,您需要设置DisablePagingExecutive
注册表项.这告诉操作系统不要将内核模式驱动程序和系统代码分页到磁盘,这是使用xperf获取64位调用堆栈的先决条件,因为64位堆栈行走取决于可执行映像中的元数据,在某些情况下xperf堆栈遍历代码不允许触摸分页页面.
这是否需要为xperf
在64位Windows上运行的32位应用程序收集数据?
在xperf
64位操作系统上收集32位进程的数据时,我应该使用x86还是x64版本?
抱歉问了这个愚蠢的问题。我是 Xperf 新手。
我使用的是 64 位 Windows 8.1,我的应用程序也是 x64。我想使用 Xperf 捕获应用程序中的调用堆栈和我定义的事件。
我在我的应用程序中注册了 GUID 35f7872e-9b6d-4a9b-a674-66f1edd66d5c
。
当我使用时:
xperf -on PROC_THREAD+LOADER+Base -start UserSession -on 35f7872e-9b6d-4a9b-a674-66f1edd66d5c -BufferSize 1024 -stackwalk profile
Run Code Online (Sandbox Code Playgroud)
我可以获得所有事件,但没有调用堆栈。但是,如果我删除-on 35f7872e-9b6d-4a9b-a674-66f1edd66d5c
并且命令行变为:
xperf -on PROC_THREAD+LOADER+Base -start UserSession -BufferSize 1024 -stackwalk profile
Run Code Online (Sandbox Code Playgroud)
这样,我就能够捕获所有调用堆栈,但没有定义的事件。
谁能告诉我用于捕获调用堆栈和事件的正确命令行是什么?另外,如果您能为我指出任何好的 Xperf 参考资料,那就更好了。