上一篇博文给大家分享了使用Windbg分析内存泄露问题:

Windbg程序调试系列2-内存泄露问题

本篇我们继续跟大家分享,如何分析解决线程阻塞问题。

从根本上讲,线程阻塞属于程序Hang的一种,其表现主要有:

1. 随着请求的增加,线程数一直增加,可能会把线程池打爆

2. 低CPU使用率(被阻塞后的CPU使用率降低)

3. 请求没有返回,客户端一直在等待,直至Timeout。

那么,从线程状态上看,什么是阻塞? 一个线程经历的5个状态,创建,就绪,运行,阻塞,终止。各个状态的转换条件如下图:

上图中有个阻塞状态,就是说当线程中调用某个函数,需要IO请求,或者暂时得不到竞争资源的,操作系统会把该线程阻塞起来,避免浪费CPU资源,等到得到了资源,再变成就绪状态,等待CPU调度运行。

线程发生阻塞的现象就是,进程的线程数会越来越多!

线程阻塞问题的分析思路:

持续请求过程中,抓两个或者三个Dump,看线程增加的速度,每次抓Dump间隔30s或者1分钟
对比的看每个Dump中:

  1. 线程池的大小 !threadpool
  2. 线程的分类和状态 !threads
  3. 查看线程阻塞 !syncblk
  4. 查看阻塞线程的根源线程、线程请求的资源对象 、被阻塞的线程数
  5. 查看阻塞根源线程的堆栈~Xs !clrstack
  6. 分析线程阻塞的原因,改进代码

1. 查看线程池的大小:!threadpool,有时间间隔两个Dump对比着看,看线程池的线程数的增长情况:

2. 查看线程的分类和线程的状态 !threads,从下图可以看出,后台线程一直在增加

3. 查看线程阻塞  !syncblk,也是看这两个dump,对比着看

我们发现:

第一个Dump中95号线程 阻塞了(1021-1)/2=510个线程
第二个Dump中79号线程 阻塞了(1099-1)/2=549个线程

95号线程独占的对象资源 00000026ba7c4dc0 (System.Object)

79号线程独占的对象资源也是00000026ba7c4dc0(System.Object)

两个线程同时锁住了同一个资源!00000026ba7c4dc0(System.Object)

此时,线程阻塞问题已经确定,接下来,我们要重点分析阻塞的根源线程(持有什么资源不释放,导致其他线程在等待),95号线程、79号线程

4. 查看阻塞线程的根源线程、线程请求的资源对象 、被阻塞的线程数

例如 95号线程:

 查看阻塞根源线程的堆栈
~95s
!clrstack

通过线程堆栈,我们在栈顶发现,95号线程,在等待Socket Server返回,具体再等哪个Socket Server?

通过以下命令找出当前线程堆栈上的Socket对象

!dso

这样我们就定位出95号线程在做什么,在等待什么:

95号线程在等待SocketServer 10.*.*.*:80返回数据,独占资源:00000026ba7c4dc0(System.Object)

同时我们通过线程堆栈看到了我们自己的一个TCP通讯类TCPInvoker, 在创建一个新的TCP连接,TCPInvoker类的代码需要重点关注,继续看!

我们继续看79号线程:

 ~79s
!clrstack

通过79号线程的堆栈和阻塞情况可以发现:

79号线程Monitor.Enter(object),在请求资源的独占锁:00000026ba7c4dc0(System.Object)

TCPInvoker卡在了GetInvoker方法上。我们需要看看TCPInvoker的代码了

5. 分析线程阻塞的原因,改进代码

从如下的代码中,我们能看到:

95号线程是执行到了GetInvoker方法的Create,Create中在等待Socket Server返回,此时如果Socket Server没有响应,超时时间默认是5s,会一直持有资源00000026ba7c4dc0(System.Object)不释放

79号线程也执行到了GetInvoker方法,但是在Lock时,等待95号线程释放资源:00000026ba7c4dc0(System.Object)

随着请求越来越多,超时+重试连接Socket Server,导致线程阻塞住了。

解决方案:1. 分析Socket Server为什么连不上 2. 优化改进TCPInvoker内部的业务逻辑,减少超时和重试时间,减少阻塞的产生几率。

好了,上面就是这次分享的Windbg调试线程阻塞问题的细节和过程,总结一下:

线程阻塞问题的分析思路:

  1. 线程池的大小 !threadpool
  2. 线程的分类和状态 !threads
  3. 查看线程阻塞 !syncblk
  4. 查看阻塞线程的根源线程、线程请求的资源对象 、被阻塞的线程数
  5. 查看阻塞根源线程的堆栈~Xs !clrstack
  6. 分析线程阻塞的原因,改进代码

周国庆

2018/11/1

Windbg程序调试系列3-线程阻塞问题的更多相关文章

  1. Windbg程序调试系列4-Live Debugging

    上篇博文中给大家分享了使用Windbg分析线程阻塞问题: Windbg程序调试系列3-线程阻塞问题 本篇中我们继续,跟大家分享附加进程实时调试-Live Debugging. 先说一下使用Windbg ...

  2. Windbg程序调试系列-索引篇

    最近整理了一下Windbg程序调试系列的文章,做个了索引贴,方便大家查询.搜索: Windbg程序调试系列1-常用命令说明&示例 Windbg程序调试系列1-Mex扩展使用总结 Windbg程 ...

  3. Windbg程序调试系列5-高CPU问题分析

    上篇博客中给大家分享了使用Windbg进行Live Debugging: Windbg程序调试系列4-Live Debugging 本篇中我们继续,跟大家分享常见的应用程序高CPU使用率问题分析. 先 ...

  4. Windbg程序调试系列1-常用命令说明&示例

    Windbg程序调试是.Net高级开发需要掌握的必备技能,分析内存泄露.分析高CPU.分析线程阻塞.分析内存对象.分析线程堆栈.Live Dedugging.这个领域可以说一个技能+场景化应用的结合, ...

  5. Windbg程序调试系列1-Mex扩展使用总结

    最近一直在频繁使用Windbg做线上Dump调试,与微软做Case交流的时候,发现微软CSS团队,用了一个非常效率的Windbg 插件,Mex: 使用介绍: https://blogs.msdn.mi ...

  6. Windbg程序调试系列2-内存泄露问题

    上篇文章给大家解释了Windbg的基本命令和说明,这一篇给大家介绍内存泄露场景的问题分析. 文章大纲: 描述问题背景和现象 确定问题是否是内存泄露 梳理问题分析思路 动手分析解决 总结 1. 先说问题 ...

  7. Windows程序调试系列: 使用VC++生成调试信息 转

    Windows程序调试系列: 使用VC++生成调试信息 ZhangTao,zhangtao.it@gmail.com, 译自 “Generating debug information with Vi ...

  8. Windbg程序调试--转载

    WinDbg是微软发布的一款相当优秀的源码级(source-level)调试工具,可以用于Kernel模式调试和用户模式调试,还可以调试Dump文件. WinDbg是微软很重要的诊断调试工具: 可以查 ...

  9. WinDbg常用命令系列---查看线程调用栈命令K*简介

    Windbg里的K*命令显示给定线程的堆栈帧以及相关信息,对于我们调试时,进行调用栈回溯有很大的帮助. 一.K*命令使用方式 在不同平台上,K*命令的使用组合如下 User-Mode, x86 Pro ...

随机推荐

  1. NOIP2017 d1t2 时间复杂度

    题目传送门:洛谷P3952 大模拟不解释 #include<iostream> #include<cstdio> #include<cmath> #include& ...

  2. C++ STL常用容器浅析

    首先要理解什么是容器,在C++中容器被定义为:在数据存储上,有一种对象类型,它可以持有其它对象或指向其它对象的指针,这种对象类型就叫做容器.简单来说 容器就是包含其他类的对象们的对象,当然这种(容器) ...

  3. Physics Experiment 弹性碰撞 [POJ3684]

    题意 有一个竖直的管子内有n个小球,小球的半径为r,最下面的小球距离地面h高度,让小球每隔一秒自由下落一个,小球与地面,小球与小球之间可视为弹性碰撞,让求T时间后这些小球的分布 Input The f ...

  4. python语法_str_eval

    dict1 = {} a = str(dict1) type(a) = 字符串 b = eval(a) type(b) = 字典

  5. SSIS - 2.使用脚本任务弹出对话框

    步骤如下: 1.打开Visual Studio 2012或者SSDT工具->单击“文件”->选择"新建"打开创建新工程的对话框如下: 2.在"Business ...

  6. 人工智能--AI篇

    AI背景 在当今互联网信息高速发展的大背景下,人工智能(AI)已经开始走进了千家万户,逐渐和我们的生活接轨,那具体什么是AI呢? 什么是人工智能(AI)? 人工智能:简单理解就是由人制造出来的,有一定 ...

  7. mongoVUE破解与配置、Mongodb数据库安装

    一.mongoVUE 1.5.3破解: 1) 开始-运行-regedit-搜索:B1159E65-821C3-21C5-CE21-34A484D54444 2.) 然后把1,2,3项数值删除,然后重新 ...

  8. in与exists和not in 与 not exists的区别

    1.in 与 exists: 外表大,用IN:内表大,用EXISTS: 原理: 用in:外表使用了索引,直接作hash连接: 用exists:内表使用了索引,外表作loop循环再进行匹配: 2.not ...

  9. subline text3 安装 rem装换工具

    CSSREM 一个CSS的px值转rem值的Sublime Text 3自动完成插件. 插件效果如下: 安装 下载本项目,比如:git clone https://github.com/flashli ...

  10. xmanager 开启X11转发失败问题解决

    安装相关rpm包 yum -y install xorg-x11-xauth xorg-x11-utils xorg-x11-fonts-* yum install dejavu-lgc-sans-f ...