首页 科技内容详情
记一次“ci” .NET 某资『zi』讯论坛 CPU爆高‘gao’分析<xi>

记一次“ci” .NET 某资『zi』讯论坛 CPU爆高‘gao’分析

分类:科技

网址:

SEO查询: 爱站网 站长工具

点击直达

皇冠APPwww.huangguan.us)是一个开放皇冠即时比分、皇冠官网注册的平台。皇冠APP(www.huangguan.us)提供最新皇冠登录,皇冠APP下载包含新皇冠体育代理、会员APP。

一:背景

1. 讲故事

大概有 you[11天没发文了,真的不是因为懒,本想前几天抽空写,不知道为啥最近求助的朋友比较多,一天都能拿到2-3个求助dump,晚上回来就是一顿分析,有点意思的是大多朋友【you】自己都分析了几遍或者公司多年的牛皮藓问题,真的是心太累,不过也好,累那是走上坡路。

再回到{dao}正题,在一个月前,有位“wei”朋友wx找到我,他最近也在‘zai’学习如何分析(xi)dump,可能经验不是很丰富,分析不下去了,截图如下:

虽然dump中(zhong)的问题千奇百怪,但如果要汇成‘cheng’大类,还是有一些规律可循的,比如:gc频繁触发,大量锁 等等,详细汇总可以观摩我的星球,好了,既然分析不下“xia”去,那就来 windbg。

二:Windbg 分析

1. 查看CPU利用率

既然报过来说cpu过高,我得用数据验证下不是,老命令 !tp


0:057> !tp
CPU utilization: 100%
Worker Thread: Total: 51 Running: 30 Idle: 0 MaxLimit: 400 MinLimit: 4
Work Request in Queue: 11
    Unknown Function: 6a0bbb30  Context: 1b4ca258
    Unknown Function: 6a0bbb30  Context: 1b4ca618
    Unknown Function: 6a0bbb30  Context: 1b4ca758
    Unknown Function: 6a0bbb30  Context: 1cb88d60
    Unknown Function: 6a0bbb30  Context: 1b4ca798
    Unknown Function: 6a0bbb30  Context: 1b5a54d0
    AsyncTimerCallbackCompletion TimerInfo@01f6e530
    Unknown Function: 6a0bbb30  Context: 1b5a5a50
    Unknown Function: 6a0bbb30  Context: 1cb892a0
    Unknown Function: 6a0bbb30  Context: 1b4ca8d8
    Unknown Function: 6a0bbb30  Context: 1cb88da0
--------------------------------------
Number of Timers: 1
--------------------------------------
Completion Port Thread:Total: 1 Free: 1 MaxFree: 8 CurrentLimit: 1 MaxLimit: 400 MinLimit: 4

我去,cpu打满了,对了,这里稍微提醒下, CPU utilization: 100% 指的是当前机器而不是程〖cheng〗序,言外之意就是当机器的CPU 100% 时,并〖bing〗不一定是你所dump的程序造成的。

2. 是否为 GC 触发

对这陌生的dump,先进行一些经验性排查,比如说是否为 GC 触发导致{zhi}? 那怎么去验证【zheng】这个假设呢? 为了让结果更准确一点,用 !t -special 导出线程列表,看看是否有 GC SuspendEE 字样『yang』。


0:057> !t -special
ThreadCount:      109
UnstartedThread:  0
BackgroundThread: 74
PendingThread:    0
DeadThread:       35
Hosted Runtime:   no

          OSID Special thread type
       14 2594 DbgHelper 
       15 2be4 GC SuspendEE 
       16  dc4 GC 
       17 2404 GC 
       18  bb4 GC 
       19 2498 Finalizer 
       20 312c ProfilingAPIAttach 
       21  858 Timer 
       22 3a78 ADUnloadHelper 
       27 290c GC 
       28 2e24 GC 
       29 28b0 GC 
       30 1e64 GC 
       38 3b24 ThreadpoolWorker 
       ...
       90 2948 Gate 

从输出看,尼玛果然有,那就表明确实是GC触发所致,如果你还不相信 xin[的话,可以参考下 coreclr 源码。


size_t
GCHeap::GarbageCollectGeneration(unsigned int gen, gc_reason reason)
{
    dprintf (2, ("triggered a GC!"));

    gc_heap::gc_started = TRUE;

    {
        init_sync_log_stats();

#ifndef MULTIPLE_HEAPS
        cooperative_mode = gc_heap::enable_preemptive ();

        dprintf (2, ("Suspending EE"));
        BEGIN_TIMING(suspend_ee_during_log);
        GCToEEInterface::SuspendEE(SUSPEND_FOR_GC);
        END_TIMING(suspend_ee_during_log);
        gc_heap::proceed_with_gc_p = gc_heap::should_proceed_with_gc();
        gc_heap::disable_preemptive (cooperative_mode);
        if (gc_heap::proceed_with_gc_p)
            pGenGCHeap->settings.init_mechanisms();
        else
            gc_heap::update_collection_counts_for_no_gc();

#endif //!MULTIPLE_HEAPS
    }
}

看到上面的 SuspendEE 的吗,它的全称就是“shi” Suspend CLR Execute Engine,接下来我们用 ~*e !dumpstack 看看哪一个线程触发了 CLR 中的 GarbageCollectGeneration 方法。

从图中‘zhong’可以看到是 58 号线程触发了,切{qie}到58号线程后换用 !clrstack

,

ERC2-usdt/TRC20-usdt互换www.u2u.it)是最高效的ERC2换TRC20,TRC20换ERC20的平台.ERC2 USDT换TRC20 USDT,TRC20 USDT换ERC20 USDT链上匿名完成,手续 xu[费低。

,

从线程栈看,程序做了一个 XXX.GetAll() 操作,一看这(zhe)名字就〖jiu〗蛮恐怖的,接下来我们再看看这块源码,到底 di[做了什么操作,简化后的源码如下:


        public static List<xxxx> GetAll()
        {
            string text = "xxxProperty_GetAll";
            SqlDatabase val = new SqlDatabase(m_strConnectionString);
            xxxPropertyTreeInfo xxxPropertyTreeInfo = null;
            List<xxxPropertieInfo> list = new List<xxxPropertieInfo>();
            DbCommand storedProcCommand = ((Database)val).GetStoredProcCommand(text);
            using (IDataReader reader = ((Database)val).ExecuteReader(storedProcCommand))
            {
                while (DataBase.DataReaderMoveNext(reader))
                {
                    xxxPropertyTreeInfo = new xxxPropertyTreeInfo();
                    xxxPropertyTreeInfo.LoadDataReader(reader);
                    list.Add(xxxPropertyTreeInfo);
                }
            }
            return list;
        }

        public virtual void LoadDataReader(MethodBase method, object obj, IDataReader reader)
        {
            Hashtable hashtable = new Hashtable();
            for (int i = 0; i < reader.FieldCount; i++)
            {
                hashtable.Add(reader.GetName(i).ToLower(), reader.GetValue(i));
            }
            Hashtable fieldProperties = GetFieldProperties(method, FieldType.DBField);
            foreach (object key in fieldProperties.Keys)
            {
                PropertyInfo p = (PropertyInfo)fieldProperties[key];
                object v = null;
                if (hashtable.Contains(key))
                {
                    v = hashtable[key];
                }
                if (v != null)
                {
                    SetPropertieValue(ref obj, ref p, ref v);
                }
            }
        }

从源码逻辑看:它执行了一个存储过程 xxxProperty_GetAll , 然后把获取到数据的 reader 和 xxxPropertyTreeInfo 做了一个 mapping 映射,在映射的过程中触发了GC。

3. 是否为数「shu」据过大导致?

按照『zhao』以往经验,应该是从数据(ju)库中获取了过多数据导致,那本次dump是不是呢?要想寻找答案, 先用 !dso 命令导出线程『cheng』栈所有变量,然后用 !do xxx 查看 List<xxxPropertieInfo> list 的size,如《ru》下图所示:

从图中看,这个size并不大,那为什么会导致gc频繁『fan』触《chu》发呢?就『jiu』算做了 反射 产生了很多的小对象,应该【gai】也没多大影响哈。。。 这又让我陷入了沉思。。。

4. 寻找问题根源

经过一顿查找,我发现了几个疑点。

  1. 有24个线程正在执行 XXX.GetALL() 方法。

  1. 托管堆中发现了 123 个 list,大的size 也有 1298,所以合【he】计起来也不小哈。。。

0:053> !dumpheap -mt 1b9eadd0
 Address       MT     Size
02572a9c 1b9eadd0       24     
026eca58 1b9eadd0       24     
0273d2a0 1b9eadd0       24 
...

Statistics:
      MT    Count    TotalSize Class Name
1b9eadd0      123         2952 System.Collections.Generic.List`1[[xxxPropertieInfo, xxx.Model]]

0:053> !DumpObj /d 28261894
Name:        System.Collections.Generic.List`1[[xxxPropertieInfo, xxx.Model]]
MethodTable: 1b9eadd0
EEClass:     6e2c6f8c
Size:        24(0x18) bytes
File:        C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
6e6ff32c  4001891        4     System.__Canon[]  0 instance 23710638 _items
6e6f1bc0  4001892        c         System.Int32  1 instance     1298 _size
6e6f1bc0  4001893       10         System.Int32  1 instance     1298 _version
6e6f0100  4001894        8        System.Object  0 instance 00000000 _syncRoot
6e6ff32c  4001895        4     System.__Canon[]  0   static  <no information>

  1. 程序是 32bit

从内存地址就能判断当前程序是 32bit,这就意味着它的 segment 段会很小,也就意味着更多的GC回收。

三:总结

本次事故是由于:

  1. 多个线程频繁重复的调用 size=1298 的 GetALL() 方法。
  2. 使用‘yong’低效的 反射方式 进行model映射,映射过{guo}程《cheng》中产生了不少的小对象。
  3. 过小的 segment (32M)

三者结合造《zao》成GC频繁的触发。

改进方法也(ye)很简单。

  • 最简单粗暴的方法: 将数据库的查 cha[询结果缓存一份。
  • 稍微正规一点方法 fa[: 用 Dapper 替换低效的 手工反射,将程序改成 64bit 。

和朋友沟通了解,采用了第一种方法,终于把 CPU 摁下去了,一切都恢复了{liao}平静!

,

欧博allbet网址www.aLLbetgame.us)是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等“deng”业务。
欧博官网 记一次“ci” .NET 某资『zi』讯论坛 CPU爆高‘gao’分析<xi> 第1张

  • usdt接口开发(www.caibao.it) @回复Ta

    2021-11-04 00:01:41 

    www.allbetgame.uswww.aLLbetgame.us),www.aLLbetgame.us开放欧博平台网址、欧博注册、欧博APP下载、欧博客户端下载、欧博游戏等业务。

    粉丝都是小宝贝

    • 新二皇冠最新手机登录(www.hg9988.vip) @回复Ta

      2021-12-01 06:29:45 

      克日,意大利政治、社会和经济研究所,意大利国际外交研究所和意大利欧亚地中海研究中央团结宣布一份名为《新疆:熟悉庞大性构建和平》的研究讲述。讲述驳倒了个体西方国家的一些政客在中国新疆问题上的谣言,力争还原事实真相。讲述的组织撰写人、意大利洛伦佐·梅迪奇国际关系研究所专家法比奥·马西莫·帕兰迪日前接受本报记者专访,讲述了组织撰写这一讲述的缘起。这个故事不错

  • usdt官方交易平台(www.usdt8.vip) @回复Ta

    2021-11-11 00:00:22 

    我没你油菜花,哈哈

    • 欧博aLLbet(www.aLLbetgame.us) @回复Ta

      2021-11-20 14:50:00 

      众所周知,著名女明星林心如曾经制作过《还珠格格》 《情深深雨蒙蒙》 《男才女貌》等优异的影视作品,在年轻一代的明星演员眼前可以算是老戏骨了。然而,观众现在不明了的是,林心如总是喜欢饰演一个女孩的角色,经常和小鲜肉一起制作偶像剧。这种行为也被许多网友质疑为装嫩。觉得缺点什么

  • 皇冠投注平台出租(www.huangguan.us) @回复Ta

    2021-11-25 00:02:24 

    在省委网信办统筹指导下,天眼新闻与省教育厅、省通信管理局、省公安厅、人行贵阳中心支行、团省委、省总工会以及省妇联等单位联合制作的网络安全短视频将同步播出,情景再现我们生活中发生的网络安全典型案例,普及网络安全知识、增强网络安全意识。一如既往的棒

  • 国内怎么买usdt(www.usdt8.vip) @回复Ta

    2021-11-26 00:03:07 

    作为一次探索、一个实验,“粤贸天下·云逛时装周”线上展销流动选择服装衣饰行业与流量电商平台连系,契合当前疫情防控形势,推动“粤贸天下”数字化生长的同时,启发了广东服装衣饰行业确立“粤贸天下”行业同伙圈,不停集结社会各方气力,培育打造创新的消费市场和动能。据领会,本次流动的商品,除广东外,主要是销往江苏、山东、浙江等省份和上海、北京、成都等都会,广东衣饰在海内有口皆碑,也受到各地消费者的追捧。我先占楼了

    • usdt线下交易(www.usdt8.vip) @回复Ta

      2021-12-05 15:29:45 

      “一湖山水,十分亲近”,英德宝墩湖·湖山温泉度假村坐落于英德客家要地,将原生态自然美景与度假旅行相连系,环境优美,比邻宝墩湖威尼斯温泉。早晨与白鹭共舞,夜晚浸身入户温泉,左拥威尼斯最长戏水乐园,右怀十里小桂林千亩原生态宝墩湖,是暑期带娃避暑的好去向。(专题 | 撰文 叶佳茵)厉害厉害,膜拜你

  • usdt币在哪里交易(www.usdt8.vip) @回复Ta

    2021-12-08 00:00:17 

    www.huangguan.us)是一个开放皇冠即时比分、皇冠官网注册的平台。皇冠注册平台(www.huangguan.us)提供最新皇冠登录,皇冠APP下载包含新皇冠体育代理、会员APP。转到朋友圈了

    • 新2足球信用平台出租(www.hg9988.vip) @回复Ta

      2021-12-18 16:26:33 

      然而,{ 现在[的海港却也泛}起了「问题」。据报道,海港的锋线上将阿瑙托维奇已经决议转会意甲球队博洛尼亚。鉴于 现在[国际的疫情状态,阿瑙很有可能在欧洲杯竣事后,不会再返回海内,“而是直接前往意大利”。榜一就是你了

发布评论