魅力程序猿

  • 首页
  • Java
  • Android
  • APP
    • 扑克计分器
    • Video Wallpaper
  • 联系我
  • 关于我
  • 资助
道子
向阳而生
  1. 首页
  2. AI技术
  3. 正文

windbg 分析线程死锁

2026年6月3日 4点热度 0人点赞 0条评论

📰 来源: 博客园


一、第一步:宏观看整体指标 !tp

  • 查看线程池Worker总数、Running/Idle、排队队列;
  • 特征:Running=总线程、Idle=0、队列积压几千 → 大批量线程永久卡死不释放。
  • 初步结论:不是瞬时并发高,是线程泄漏卡死。
  • 二、第二步:排查托管锁 !syncblk

  • 看每条:MonitorHeld=占用数、有无等待的Waiter线程
  • ① 有大量等待线程 = 多lock互相争抢,传统Monitor死锁
  • ② 只有占用、无等待线程 = 线程拿着锁卡在业务代码,锁是副产品,不是元凶(你的场景)
  • 三、第三步:抽卡死线程栈(从syncblk里提取OS-TID)

    ~~[0xTID]s;!clrstack 打印单个卡死线程托管堆栈:

  • 栈出现:ManualResetEventSlim.Wait → Task.InternalWait → Task.Wait()
    → 锁定:同步.Wait()阻塞异步任务,上下文死锁。
  • 向上追溯业务类:定位出事方法(ServiceDiscovery、MatrixHelper、HttpModule、Controller)。
  • 四、第四步:结合代码解释「偶发正常、随机卡死」

  • 命中缓存/连接复用:GetAsync同步执行完毕,返回已完成Task,await不放线程,全链路顺行,正常释放;
  • 真实跨网IO:返回未完成Task,await释放工作线程;IO完成回调要切回AspNetSynchronizationContext,但主线程被.Wait()占死 → 闭环死锁、线程永久滞留。
  • 五、第五步:区分两种死锁、落地修复

  • 传统lock死锁:A拿锁1等锁2、B拿锁2等锁1 → 改锁顺序、缩小lock范围;
  • ASP上下文死锁(本次故障):同步.Wait()/Result + await无ConfigureAwait(false)
    修复二选一:

    • 方案1:全链路改成async/await,删除所有.Wait();
    • 方案2:所有await xxx.ConfigureAwait(false),切断回调绑定请求上下文。
  • 方案1:全链路改成async/await,删除所有.Wait();
  • 方案2:所有await xxx.ConfigureAwait(false),切断回调绑定请求上下文。
  • !tp看池子满不满,!syncblk辨锁死还是卡死,切线程栈找Wait,缓存决定偶发好坏


    🔗 原文链接: 点击阅读原文

    标签: AI 人工智能 技术博客
    最后更新:2026年6月3日

    daozi

    这个人很懒,什么都没留下

    点赞
    < 上一篇

    文章评论

    您需要 登录 之后才可以评论
    搜索
    联系方式

    QQ群:179730949
    QQ群:114559024
    欢迎您加入Android大家庭
    本人QQ:136049925

    赐我一丝安慰
    给我一点鼓励

    COPYRIGHT © 2023 魅力程序猿. ALL RIGHTS RESERVED.

    Theme Kratos Made By Seaton Jiang

    豫ICP备15000477号