WinDbg调试C#技巧,解决CPU过高、死锁、内存爆满
软件安装
安装问题:执行 .loadby sos clr 命令无效
解决办法:
.load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SOS.dll
.load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
.loadby sos clr
代码调试
查看线程
命令: !threads
执行结果:
进入线程
命令: ~~[线程Id]s
执行结果:
查看线程详情
命令: !clrstack
执行结果:
查看线程状态
命令: !ThreadState 线程StateId
执行结果:
退出附加进程
命令: qd
查看线程环境块(空间)
命令: !Teb
执行结果:
查看线程堆栈
命令: !dumpstack
执行结果:
查看局部变量
命令: !clrstack
!clrstack -l
执行结果:
查看帮助
命令: !help
执行结果:
查看终结器队列
命令: !FinalizeQueue
执行结果:
查看线程池详情
命令: !threadpool
执行结果:
查看查看当前托管线程已执行时间
命令: !runaway
执行结果:
清屏
命令: !cls
查看查看当前托管线程已执行时间
命令: ~*e!clrstack
执行结果:看所有线程的堆栈
CPU过高的问题
模拟CPU过高
示例代码:
class Program
{
static void Main(string[] args)
{
Run(); Console.Read();
} static void Run()
{
var task = Task.Factory.StartNew(() =>
{
//这是一个非常复杂的逻辑,导致死循环
while (true)
{ }
});
}
}
生成64位Realease版本代码:
在Bin/Realse下找到文件并运行,然后查看CPU:
解决CUP占用过高
创建转储文件:
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
找到该转储文件:C:\Users\ADMINI~1\AppData\Local\Temp\ConsoleApp4.DMP
用X64版本的WinDbg打开DMP文件:
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
然后打开命令输入:
然后输入 .loadby sos clr 与 !threads
现在线程少没有关系,多的话我们没有办法去判断哪个线程消耗严重,所以执行 !runaway 查看当前托管线程已执行时间
切换到指定线程 ~~[4f78]s ,执行 !clrstack 查看当前线程的调用堆栈
从调用堆栈上来看,当前线程 在 Program+c.b__1_0() 方法之后23行就没有调用堆栈了,说明方法在这个地方停滞不前了。
最后反编译源码到指定的方法中去查看
方法二:
通过 !dumpdomain 拿到程序地址
然后反编译成dll输出文件 !savemodule 00007ff7e4f94120 c:\\.dll (文件夹必须存在)
然后找到该dll进行反编译
死锁问题
模拟死锁
实例代码:
class Program
{
static void Main(string[] args)
{
new Program().Run(); Console.Read();
} void Run()
{
lock (this)
{
var task = Task.Factory.StartNew(() =>
{
Console.WriteLine("-------start-------");
Thread.Sleep(); Run2();
Console.WriteLine("---------end--------");
}); task.Wait();
}
} void Run2()
{
lock (this)
{
Console.WriteLine("------我是Run2------");
}
}
}
执行结果:
解决死锁
然后用WinDbg附加到进程,执行 .loadby sos clr 与 !threads 查看当前的托管线程
然后执行 ~*e!clrstack 查看所有线程的堆栈
可以看出主线程在等待
执行 !syncblk 查看当前哪个线程持有锁,可以看出主线程持有锁
可以看得出“主线程”持有当前的同步锁
内存爆满
模拟内存爆满
实例代码:
class Program
{
static StringBuilder sb = new StringBuilder();
static void Main(string[] args)
{
for (int i = ; i < ; i++)
{
sb.Append("hello world");
} Console.WriteLine("执行完毕");
Console.Read();
}
}
解决内存爆满
然后用WinDbg附加到进程,执行 .loadby sos clr 与 !threads ,然后执行 !dumpheap -stat 查看clr的托管堆中的各个类型的占用情况
然后看到了有13768个char[]数组
然后执行 !DumpHeap /d -mt 00007ff841318610 //查看当前的方法表
然后执行 !DumpObj /d 0000022baed1dec8 //查看当前char[]的内容
然后执行 !gcroot 00000135a60f4940 查看当前地址的Root。。。
所以结合“StringBuilder”,结合 ”hello world“ 我们就找出了问题。。。
WinDbg调试C#技巧,解决CPU过高、死锁、内存爆满的更多相关文章
- Java中的CPU占用高和内存占用高的问题排查
下面通过模拟实例分析排查Java应用程序CPU和内存占用过高的过程.如果是Java面试,这2个问题在面试过程中出现的概率很高,所以我打算在这里好好总结一下. 1.Java CPU过高的问题排查 举个例 ...
- WINDBG解决cpu占高的问题
https://blog.csdn.net/yenange/article/details/62886988 https://blog.csdn.net/zhushentian/article/det ...
- 用windbg+sos找出程序中谁占用内存过高,谁占用CPU过高(转载)
原文地址: http://www.cnblogs.com/Lawson/archive/2011/01/23/1942692.html 很早看到windbg+sos方面的知识,一直没仔细学习,也许因为 ...
- MySQL CPU 使用率高的原因和解决方法
用户在使用 MySQL 实例时,会遇到 CPU 使用率过高甚至达到 100% 的情况.本文将介绍造成该状况的常见原因以及解决方法,并通过 CPU 使用率为 100% 的典型场景,来分析引起该状况的原因 ...
- 记一次查内存异常问题(续《记一次Web应用CPU偏高》)
继上一次查应用的CPU飙高问题(http://www.cnblogs.com/hzmark/p/JVM_CPU.html)过去10天了.上次只是定位到了是一个第三方包占用了大量的CPU使用,但没有细致 ...
- Oracle SQL CPU占用高
Oracle数据库经常会遇到CPU利用率很高的情况,这种时候大都是数据库中存在着严重性能低下的SQL语句,这种SQL语句大大的消耗了CPU资源,导致整个系统性能低下.当然,引起严重性能低下的SQL语句 ...
- JVM进程cpu飙高分析
在项目快速迭代中版本发布频繁 近期上线报错一个JVM导致服务器cpu飙高 但内存充足的原因现象. 对于耗内存的JVM程序来而言, 基本可以断定是线程僵死(死锁.死循环等)问题. 这里是纪录一下排 ...
- 再记一次w3wp占用CPU过高的解决过程(Dictionary和线程安全)
在此之前项目有发生过两次类似的状况,都得以解决,但最近又会发现偶尔CPU会跑满,虽然之前使用过WinDbg解决过两次问题但人的记忆是不可靠的,今天处理同样问题的时候还是遇到了一些障碍,这一次希望可以记 ...
- zprofiler三板斧解决cpu占用率过高问题(转载)
zprofiler三板斧解决cpu占用率过高问题 九居 JVM性能与调试平台 zprofiler 上周五碰到了一个线上机器cpu占用率过高的问题.问题本身比较简单,但是定位过程中动用了多个zp ...
随机推荐
- too many open files linux服务器 golang java
1. 现象 服务的cpu跑满(golang实现), 并大量报too many open files错误.服务使用systemd来运行,部署在阿里ecs上. 2.分析 从日志来看,cpu的上升主要为到达 ...
- luoguP4231_三步必杀_差分
luoguP4231_三步必杀_差分 题意:N 个柱子排成一排,一开始每个柱子损伤度为0.接下来勇仪会进行M 次攻击,每次攻击可以用4个参数l,r ,s ,e 来描述: 表示这次攻击作用范围为第l个到 ...
- 查询APP Store已发布过的版本记录
1.国内APP使用 酷传 搜索,即可查询到版本记录 2.国外的APP 无法通过国内软件进行搜索,可在App store中直接查询.步骤如下:
- 【STM32H7教程】第4章 STM32H7工程模板建立(MDK5)
完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第4章 STM32H7工程模板建立(MDK5) 本章 ...
- Spark学习之编程进阶总结(二)
五.基于分区进行操作 基于分区对数据进行操作可以让我们避免为每个数据元素进行重复的配置工作.诸如打开数据库连接或创建随机数生成器等操作,都是我们应当尽量避免为每个元素都配置一次的工作.Spark 提供 ...
- 跳动在网页中间的精灵----Javascript
今天开始js的内容整理,跳动在网页里的精灵就是它了. 一.简介 1.什么是Javascript JavaScript 是一种具有面向对象能力的.解释型的程序设计语言.更具体一点,它是基于对象和事件驱动 ...
- [区块链] 共识算法之争(PBFT,Raft,PoW,PoS,DPoS,Ripple)
近几天对区块链中几种常见的共识机制(PBFT,Raft,PoW,PoS,DPoS,Ripple)进行了总结.尽量使用简单易懂语言,篇幅较大,想了解的可以只读每个算法介绍中前边的原理.本篇文章主要参考& ...
- Java8新特性之二:方法引用
上一节介绍了Java8新特性中的Lambda表达式,本小节继续讲解Java8的新特性之二:方法引用.方法引用其实也离不开Lambda表达式. 1.方法引用的使用场景 我们用Lambda表达式来实现匿名 ...
- Itest(爱测试),最懂测试人的开源测试管理软件隆重发布
测试人自己开发,汇聚10年沉淀,独创流程驱动测试.度量展现测试人价值的测试协同软件,开源免费 官网刚上线,近期发布源码:http://www.itest.work 在线体验 http://www. ...
- Java进阶篇设计模式之七 ----- 享元模式和代理模式
前言 在上一篇中我们学习了结构型模式的组合模式和过滤器模式.本篇则来学习下结构型模式最后的两个模式, 享元模式和代理模式. 享元模式 简介 享元模式主要用于减少创建对象的数量,以减少内存占用和提高性能 ...