记一次 .NET 某工控数据采集平台 线程数 爆高分析

一:背景

1. 讲故事

前几天有位朋友在 B站 加到我,说他的程序出现了 线程数 爆高的问题,让我帮忙看一下怎么回事,截图如下:

记一次 .NET 某工控数据采集平台 线程数 爆高分析

说来也奇怪,这些天碰到了好几起关于线程数无缘无故的爆高,不过那几个问题比这一篇要复杂的多,主要涉及到非托管层面,分享这一篇的目的主要是它很有代表性,很有必要。

闲话不多说,既然线程数爆高,那就上 windbg 说话。

二:WinDbg 分析

1. 线程数真的高吗

既然说线程数高,那到底有多少呢? 我们可以用 !t 命令看一下。


0:000> !t
ThreadCount:      109
UnstartedThread:  0
BackgroundThread: 104
PendingThread:    0
DeadThread:       1
Hosted Runtime:   no
                                                                         Lock
       ID OSID ThreadOBJ    State GC Mode     GC Alloc Context  Domain   Count Apt Exception
   0    1 2970 00581020     26020 Preemptive  0294AE60:00000000 0057a5f0 0     STA
   2    2 1d2c 00590670     2b220 Preemptive  00000000:00000000 0057a5f0 0     MTA (Finalizer)
   5    4 3388 0063a9b8   102a220 Preemptive  00000000:00000000 0057a5f0 0     MTA (Threadpool Worker)
   6    5 265c 0063b458   1020220 Preemptive  00000000:00000000 0057a5f0 0     Ukn (Threadpool Worker)
   7    7 3370 07100fa8   202b220 Preemptive  00000000:00000000 0057a5f0 0     MTA
 ...

 113   41 4af4 0a85a490   8029220 Preemptive  0294F918:00000000 0057a5f0 0     MTA (Threadpool Completion Port)
 114   75 4b9c 0a83d818   8029220 Preemptive  00000000:00000000 0057a5f0 0     MTA (Threadpool Completion Port)
 115   76 4ba0 0a83d2d0   8029220 Preemptive  02B53AC4:00000000 0057a5f0 0     MTA (Threadpool Completion Port)

从卦象看,当前有 115 个托管线程,从主线程的 STA 模式看 应该是一个 WinForm/WPF 程序,桌面程序这个线程数说多也不多,说少也不少,下一步的思路就是看下这些线程都在做什么。

2. 这些线程都在做什么

要探究每个线程都在做什么,可以用 ~*e !clrstack 调出所有线程栈,然后仔细耐心的观察这些线程。


0:000> ~*e !clrstack
OS Thread Id: 0x488c (109)
Child SP       IP Call Site
114de760 7704018d [GCFrame: 114de760]
114de90c 7704018d [GCFrame: 114de90c]
114de8bc 7704018d [HelperMethodFrame: 114de8bc] System.Threading.Monitor.ReliableEnter(System.Object, Boolean ByRef)
114de94c 6dfe2767 System.Threading.Monitor.Enter(System.Object, Boolean ByRef)
114de95c 056107e3 CSRedis.Internal.IO.RedisIO.Write(Byte[])
114de998 05cb338c CSRedis.Internal.RedisConnector.Write(CSRedis.RedisCommand)
114de9dc 05cb32fc CSRedis.Internal.RedisListener1[[System.__Canon, mscorlib]].Write[[System.__Canon, mscorlib]](CSRedis.RedisCommand1)
114de9f0 05cb3263 CSRedis.Internal.SubscriptionListener.Send(CSRedis.Internal.Commands.RedisSubscription)
114dea0c 050c4ffd CSRedis.RedisClient.Unsubscribe(System.String[])
114dea24 050c01e3 CSRedis.CSRedisClient+SubscribeObject+c__DisplayClass13_0.b__1(System.Object)
114deab4 6e026471 System.Threading.TimerQueueTimer.CallCallbackInContext(System.Object)
114deab8 6dfe2925 System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
114deb24 6dfe2836 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
114deb38 6e026377 System.Threading.TimerQueueTimer.CallCallback()
114deb6c 6e0261fe System.Threading.TimerQueueTimer.Fire()
114debac 6e02612f System.Threading.TimerQueue.FireNextTimers()
114debec 6e025ff1 System.Threading.TimerQueue.AppDomainTimerCallback()
114dee10 6f38eaf6 [DebuggerU2MCatchHandlerFrame: 114dee10]
...

记一次 .NET 某工控数据采集平台 线程数 爆高分析

从卦象看,线程特征非常明显,有 86 个线程卡在 Monitor.ReliableEnter 处,它就是我们C#中的 监视锁 ,既然是监视锁,那就好办了,查看它的 同步块表,看看谁在 lock 里赖着不出来导致其他线程等待,使用 windbg 的 !syncblk 命令。

`c#

0:000> !syncblk
Index SyncBlock MonitorHeld Recursion Owning Thread Info SyncBlock Owner
72 005ef1f0 87 1 07176838 12c8 13 028374e4 System.Object
75 005efd1c 87 1 07176d80 32c0 14 028368ec System.Object

Original: https://www.cnblogs.com/huangxincheng/p/16443889.html
Author: 一线码农
Title: 记一次 .NET 某工控数据采集平台 线程数 爆高分析

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/541836/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • SpringMVC工作流程

    SpringMVC 1、MVC Model(模型)+View(视图)+Controller(控制器),通过将业务逻辑、数据、显示分离来组织代码。 Service层(处理业务)、Da…

    Java 2023年6月5日
    082
  • 1、编译系统

    1 编译系统 1.1 引入编译系统 1.2 编译系统的组成 1.2.1 预处理器 1.2.2 编译器 1.2.3 汇编器 1.2.4 链接器 2 GCC 3 编译过程演示 3.1 …

    Java 2023年6月7日
    067
  • Java设计模式之(九)——门面模式

    Provide a unified interface to a set of interfaces in a subsystem.Facade defines a higher-…

    Java 2023年5月29日
    064
  • Springboot+Vue前后端分离demo

    一、后端工作 1、创建数据库 数据库名shop_v1.0,字符集utf8,排序规则utf8_general_ci,执行脚本。 CREATE TABLE t_user ( id bi…

    Java 2023年6月5日
    0109
  • Nginx中的rewrite指令(break,last,redirect,permanent)

    在server块下,会优先执行rewrite部分,然后才会去匹配location块 server中的rewrite break和last没什么区别,都会去匹配location,所以…

    Java 2023年5月30日
    073
  • NLP中的语言模型预训练相关总结

    NLP中的语言模型预训练相关总结 NLP中的语言模型预训练相关总结 前言 one-hot 模型 word2vec模型 ELMO模型 Open AT GPT Bert 总结 参考资料…

    Java 2023年6月7日
    051
  • Java 将HTML转为XML

    本文介绍如何通过Java后端程序代码来展示如何将html转为XML。此功能通过采用Word API- Free Spire.Doc for Java 提供的 Document.sa…

    Java 2023年5月29日
    064
  • 《深入理解Java虚拟机》并发(第12~13章)笔记

    volatile关键字的作用 所有变量的可见性——仅仅是修改后的值的可见性,不保证并发修改时新值和预期一致。即只保证读,不保证写。 禁止指令重排序——修饰的变量,读写不会指令重排。…

    Java 2023年5月29日
    061
  • 总结一下今天所学的知识9.18

    一种是将client和controller层实现一个共同的接口 — 这种方式的话耦合度非常高,而且形参中的注解不会被继承,所以controller中仍然需要注明形参列表…

    Java 2023年6月15日
    047
  • spring-retry使用

    Spring Retry提供了自动重新调用失败的操作的功能。这在错误可能是暂时性的(例如瞬时网络故障)的情况下很有用。Spring Retry提供对流程和基于策略的行为的声明式控制…

    Java 2023年5月30日
    095
  • java8特性

    Lambda表达式 lambda表达式:本质就是一个函数式接口的实例对象。 语法: lambda形参列&#…

    Java 2023年6月15日
    071
  • nginx 负载均衡集群解决方案 healthcheck_nginx_upstreams (一)

    该文章来源于互联网,目前找不到原作者,放在这里的目的是记录healthcheck_nginx_upstreams的安装过程和相关配置,在起初安装成功后不能够正常运行healthch…

    Java 2023年5月30日
    080
  • java释放资源、try()用法

    不用写一大堆finally来关闭资源,所有实现Closeable的类声明都可以写在里面,最常见于流操作,socket操作,新版的httpclient也可以;需要注意的是,try()…

    Java 2023年5月29日
    058
  • 基于 vite 创建 vue3 全家桶项目(vite + vue3 + tsx + pinia)

    vite 最近非常火,它是 vue 作者尤大神发布前端构建工具,底层基于 Rollup,无论是启动速度还是热加载速度都非常快。vite 随 vue3 正式版一起发布,刚开始的时候与…

    Java 2023年6月16日
    051
  • MyBatis(二六):缓存——缓存原理

    首先来思考一下,在开启了二级缓存的情况下,一个用户查询数据经历的过程是什么样的。 我们看一下,下面这张图: 用户先去二级缓存中去寻找数据,如果找不到再去一级缓存寻找数据,如果还是找…

    Java 2023年6月15日
    083
  • 两个变量数值交换

    交换两个变量的值yi 一:使用第三个变量 二:不使用第三个变量 来点伤心史💔 //        i=minIndext //        自身加自身 结果改变自身 //    …

    Java 2023年6月8日
    071
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球