.net 在IIS进程上调试高CPU使用率 IIS进程上的高CPU使用率
我目前正在调查我们的一台生产服务器上的高CPU使用率,我被卡住了,希望这里的人能够提供帮助。将CPU使用率与入站web服务调用(WCF和REST)的数量进行比较,可以看出它们是不相关的,每当调用增加或减少时,CPU使用率似乎都会上升 设置.net 在IIS进程上调试高CPU使用率 IIS进程上的高CPU使用率,.net,performance,debugging,iis,.net,Performance,Debugging,Iis,我目前正在调查我们的一台生产服务器上的高CPU使用率,我被卡住了,希望这里的人能够提供帮助。将CPU使用率与入站web服务调用(WCF和REST)的数量进行比较,可以看出它们是不相关的,每当调用增加或减少时,CPU使用率似乎都会上升 设置 Windows 2012 R2服务器x64 IIS 8.5 .NET 4.5 运行我们的应用程序的单个应用程序池 00:00时自动回收应用程序池 问题 最近,我们的CPU使用率急剧增加,这种模式似乎是CPU使用率从午夜开始攀升(我回收了池),并一直攀升,直
- Windows 2012 R2服务器x64
- IIS 8.5
- .NET 4.5
- 运行我们的应用程序的单个应用程序池
- 00:00时自动回收应用程序池
0:047> !runaway
User Mode Time
Thread Time
47:2920 0 days 0:24:42.921
49:1f1c 0 days 0:23:07.796
52:2ed8 0 days 0:21:38.218
54:1560 0 days 0:21:37.937
48:273c 0 days 0:21:19.140
59:2110 0 days 0:20:56.078
45:2d90 0 days 0:20:35.906
...
19:1c88 0 days 0:00:00.000
(此处仅显示一些线程)
因此,我尝试查看这些线程中发生了什么,因为这不是预期的行为。所有具有长时间运行任务的线程似乎都可以管理,但每当我尝试时!clrstack在我得到的任何一个上:
0:047> !clrstack
OS Thread Id: 0x2920 (47)
Child SP IP Call Site
GetFrameContext failed: 1
0000000000000000 0000000000000000 <unknown>
这让我相信线程正在等待一些资源(这是正确的吗?),这就是我真正迷路的地方!
轨迹中线的情况是:
0000009c46eaefe0 00007fff0c3b1387 00007fff0c3b1387
0000009c46eaf030 00007fff04c111d2 00007fff04c111d2, calling 00007fff04c11070
我的猜测是,一些管理的东西正在这里发生,但为什么是!那我就不工作了?
通过查看第一个帧,我看到它正在等待某个资源句柄。我看起来手柄是0xa,但我还不能确定这一点。看着把手!处理0xa ff我得到以下结果:
0:047> !handle 0xa ff
Handle 000000000000000a
Type File
Attributes 0
GrantedAccess 0x100020:
Synch
Execute/Traverse
HandleCount 2
PointerCount 65535
No object specific information available
告诉我这指向一个文件,但什么文件,我如何从这里继续?看着其他的顶级T台线程给我同样的图片
呼救声
我知道这是一个巨大的任务,但我真的需要帮助从这里开始。我是在正确的轨道上,还是只是在黑暗中摸索?
任何帮助都将不胜感激
新闻
在我们的IT部门使用一些我觉得有趣的计数器记录一个perfMon数据集之后,我得出了一个结论:1)我们正在泄漏线程2)GC正在发疯(可能是因为泄漏)。
关于如何检测导致螺纹泄漏的原因有什么想法吗?
请参见此处的计数器:
在发现我们正在泄漏线程后,我一直在研究我们的代码,并发现了一些感兴趣的代码:
// Initialize TimerExecutionEveryMinute timer
const double timeConversion = 60 * 1000; //convert one minute to milliseconds
var timer1 = new System.Timers.Timer { Enabled = true, Interval = timeConversion };
timer1.Elapsed += TimerExecutionEveryMinute;
然后:
// Execution every minute
public static void TimerExecutionEveryMinute(object sender, EventArgs e)
{
var jpsLogger = KernelContainer.Kernel.Get<IJpsLogger>();
// Initialize MemBag
MemBag.Log.ActivityIdReset(Guid.NewGuid());
MemBag.Log.BaseType = "TimerExecution";
MemBag.Log.BaseClass = "Timer";
MemBag.Log.BaseMethod = "TimerExecutionEveryMinute";
// Statistic timer job
var t1 = jpsLogger.Trace.SpecializedDebug("Analyses.OneMinuteTimer", "One minute timer begin");
var t2 = jpsLogger.Trace.SpecializedDebug("Analyses.OneMinuteTimer", " Method.WriteDB begin");
Method.WriteDB();
jpsLogger.Trace.SpecializedDebug("Analyses.OneMinuteTimer", " Method.WriteDB end", t2);
t2 = jpsLogger.Trace.SpecializedDebug("Analyses.OneMinuteTimer", " Memory.LogCurrentState begin");
Memory.LogCurrentState();
jpsLogger.Trace.SpecializedDebug("Analyses.OneMinuteTimer", " Memory.LogCurrentState end", t2);
//Calculates the CPU load based on samples taken at every timer step
t2 = jpsLogger.Trace.SpecializedDebug("Analyses.OneMinuteTimer", " CPU load begin");
CPULogger.LogCpu();
jpsLogger.Trace.SpecializedDebug("Analyses.OneMinuteTimer", " CPU load end", t2);
// Dump log information to file
t2 = jpsLogger.Trace.SpecializedDebug("Analyses.OneMinuteTimer", " FileLogger.WriteAsync begin");
FileLogger.WriteAsync();
jpsLogger.Trace.SpecializedDebug("Analyses.OneMinuteTimer", " FileLogger.WriteAsync end", t2);
jpsLogger.Trace.SpecializedDebug("Analyses.OneMinuteTimer", "One minute timer end", t1);
}
//每分钟执行一次
公共静态无效TimerExecutionEveryMinute(对象发送方,事件参数e)
{
var jpsLogger=KernelContainer.Kernel.Get();
//初始化内存包
MemBag.Log.ActivityIdReset(Guid.NewGuid());
MemBag.Log.BaseType=“TimerExecution”;
MemBag.Log.BaseClass=“计时器”;
MemBag.Log.BaseMethod=“TimerExecutionEveryMinute”;
//统计计时器作业
var t1=jpsLogger.Trace.SpecializedDebug(“analysis.OneMinuteTimer”,“一分钟计时器开始”);
var t2=jpsLogger.Trace.SpecializedDebug(“analysis.OneMinuteTimer”,“Method.WriteDB begin”);
方法WriteDB();
jpsLogger.Trace.SpecializedDebug(“analysis.OneMinuteTimer”,“Method.writedbend”,t2);
t2=jpsLogger.Trace.SpecializedDebug(“analysis.OneMinuteTimer”,“Memory.LogCurrentState begin”);
Memory.LogCurrentState();
jpsLogger.Trace.SpecializedDebug(“analysis.OneMinuteTimer”,“Memory.LogCurrentState end”,t2);
//根据在每个计时器步骤中采集的样本计算CPU负载
t2=jpsLogger.Trace.SpecializedDebug(“analysis.OneMinuteTimer”,“CPU加载开始”);
CPULogger.LogCpu();
jpsLogger.Trace.SpecializedDebug(“分析.一分钟计时器”,“CPU加载结束”,t2);
//将日志信息转储到文件
t2=jpsLogger.Trace.SpecializedDebug(“analysis.OneMinuteTimer”、“FileLogger.WriteAsync begin”);
WriteAsync();
jpsLogger.Trace.SpecializedDebug(“analysis.OneMinuteTimer”,“FileLogger.WriteAsync end”,t2);
jpsLogger.Trace.SpecializedDebug(“分析.一分钟计时器”,“一分钟计时器结束”,t1);
}
这可能是漏水的地方吗?我相信System.Timers.Timer在我每次创建事件时都会启动新线程,而且它是线程安全的,所以我会在执行代码周围创建锁,代码每分钟执行一次,以及其他写入日志文件的事情,我的论文如果对文件的访问被阻止,线程不断堆积,这将解释逻辑线程数量线性增加的原因,如所示,我没有答案,但让我尝试给出一些提示 在你的问题中你提到 最近我们的CPU使用量急剧增加 这是否意味着该应用程序以前工作正常?如中所示,您是否意识到没有异常的CPU峰值 如果是这样,那么你需要看看最近发生了什么变化:
- 是否为您的应用程序部署了任何新代码,特别是分配大量数据的代码
- 是否在服务器上安装了任何更新,如果是,您是否可以对其进行审核,并检查可能提到您遇到的症状的任何Microsoft知识库文章(或者简单地搜索更新名称,查看是否有博客提到它们)
// Execution every minute
public static void TimerExecutionEveryMinute(object sender, EventArgs e)
{
var jpsLogger = KernelContainer.Kernel.Get<IJpsLogger>();
// Initialize MemBag
MemBag.Log.ActivityIdReset(Guid.NewGuid());
MemBag.Log.BaseType = "TimerExecution";
MemBag.Log.BaseClass = "Timer";
MemBag.Log.BaseMethod = "TimerExecutionEveryMinute";
// Statistic timer job
var t1 = jpsLogger.Trace.SpecializedDebug("Analyses.OneMinuteTimer", "One minute timer begin");
var t2 = jpsLogger.Trace.SpecializedDebug("Analyses.OneMinuteTimer", " Method.WriteDB begin");
Method.WriteDB();
jpsLogger.Trace.SpecializedDebug("Analyses.OneMinuteTimer", " Method.WriteDB end", t2);
t2 = jpsLogger.Trace.SpecializedDebug("Analyses.OneMinuteTimer", " Memory.LogCurrentState begin");
Memory.LogCurrentState();
jpsLogger.Trace.SpecializedDebug("Analyses.OneMinuteTimer", " Memory.LogCurrentState end", t2);
//Calculates the CPU load based on samples taken at every timer step
t2 = jpsLogger.Trace.SpecializedDebug("Analyses.OneMinuteTimer", " CPU load begin");
CPULogger.LogCpu();
jpsLogger.Trace.SpecializedDebug("Analyses.OneMinuteTimer", " CPU load end", t2);
// Dump log information to file
t2 = jpsLogger.Trace.SpecializedDebug("Analyses.OneMinuteTimer", " FileLogger.WriteAsync begin");
FileLogger.WriteAsync();
jpsLogger.Trace.SpecializedDebug("Analyses.OneMinuteTimer", " FileLogger.WriteAsync end", t2);
jpsLogger.Trace.SpecializedDebug("Analyses.OneMinuteTimer", "One minute timer end", t1);
}
GC.GetTotalMemory(true)