精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

AOT漫談: 如何獲取C#程序的CPU利用率

開發 前端
如果你的AOT使用默認的 WindowsThreadPool,那想獲取 cpu利用率基本上是無力回天,當然有達人知道的話可以告知下,如果切到默認的.NET線程池還是有的一拼,即使沒有 pdb 符號也可以根據_minThreads和_maxThreads的內容反向搜索。

一、背景

1. 講故事

上篇聊到了如何對AOT程序進行輕量級的APM監控,有朋友問我如何獲取AOT程序的CPU利用率,本來我覺得這是一個挺簡單的問題,但一研究不是這么一回事,這篇我們簡單的聊一聊。

二、如何獲取CPU利用率

1. 認識cpuUtilization字段

熟悉.NET底層的朋友應該知道,.NET線程池中有一個cpuUtilization字段就記錄了當前機器的CPU利用率,所以接下來的思路就是如何把這個字段給挖出來,在挖這個字段之前也要知道 .NET6 為界限出現過兩個線程池。

1)win32threadpool.cpp

這是 .NET6 之前一直使用的 .NET線程池,它是由 clr 的 1)win32threadpool.cpp 實現的,參考代碼如下:

SVAL_IMPL(LONG,ThreadpoolMgr,cpuUtilization);
PortableThreadPool.cs

為了更好的跨平臺以及高層統一, .NET團隊用C#對原來的線程池進行了重構,所以這個字段自然也落到了C#中,參考如下:

internal sealed class PortableThreadPool
{
    private int _cpuUtilization;
}
WindowsThreadPool.cs

我原以為線程池已經被這兩種實現平分天下,看來我還是年輕了,不知道什么時候又塞入了一種線程池實現 WindowsThreadPool.cs,無語了,它是簡單的 WindowsThreadPool 的 C#封裝,舍去了很多原來的方法實現,比如:

internal static class WindowsThreadPool
{
    public static bool SetMinThreads(int workerThreads, int completionPortThreads)
    {
        return false;
    }
    public static bool SetMaxThreads(int workerThreads, int completionPortThreads)
    {
        return false;
    }

    internal static void NotifyThreadUnblocked()
    {
    }

    internal unsafe static void RequestWorkerThread()
    {
        //todo...
        //提交到 windows線程池
        Interop.Kernel32.SubmitThreadpoolWork(s_work);
    }
}

而這個也是 Windows 版的AOT默認實現,因為 Windows線程池是由操作系統實現,沒有源碼公開,觀察了reactos的開源實現,也未找到類似的cpuUtilization字段,這就比較尷尬了,常見的應對措施如下:

  1. 因為dump或者program中沒有現成字段,只能在程序中使用代碼獲取。
  2. 修改windows上的 aot 默認線程池。

2. 如果修改AOT的默認線程池

在微軟的官方文檔:https://learn.microsoft.com/zh-cn/dotnet/core/runtime-config/threading 上就記錄了Windows線程池的一些概況以及如何切換線程池的方法,截圖如下:

圖片圖片

這里選擇 MSBuild 的方式來配置。

<Project Sdk="Microsoft.NET.Sdk">

 <PropertyGroup>
  <OutputType>Exe</OutputType>
  <TargetFramework>net8.0</TargetFramework>
  <ImplicitUsings>enable</ImplicitUsings>
  <Nullable>enable</Nullable>
  <PublishAot>true</PublishAot>
  <UseWindowsThreadPool>false</UseWindowsThreadPool>
  <InvariantGlobalization>true</InvariantGlobalization>
 </PropertyGroup>
</Project>

接下來寫一段簡單的C#代碼,故意讓一個線程死循環。

internal class Program
    {
        static void Main(string[] args)
        {
            Task.Run(() =>
            {
                Test();
            }).Wait();
        }

        static void Test()
        {
            var flag = true;
            while (true)
            {
                flag = !flag;
            }
        }
    }

這里要注意的一點是發布成AOT的程序不能以普通的帶有元數據的C#程序來套。畢竟前者沒有元數據了,那怎么辦呢?這就考驗你對AOT依賴樹的理解,熟悉AOT的朋友都知道,依賴樹的構建最終是以有向圖的方式存儲在 _dependencyGraph 字段中,每個節點由基類 NodeFactory 承載,參考代碼如下:

public abstract class Compilation : ICompilation
{
    protected readonly DependencyAnalyzerBase<NodeFactory> _dependencyGraph;
}

public abstract partial class NodeFactory
{
    public virtual void AttachToDependencyGraph(DependencyAnalyzerBase<NodeFactory> graph)
    {
        ReadyToRunHeader = new ReadyToRunHeaderNode();

        graph.AddRoot(ReadyToRunHeader, "ReadyToRunHeader is always generated");
        graph.AddRoot(new ModulesSectionNode(), "ModulesSection is always generated");

        graph.AddRoot(GCStaticsRegion, "GC StaticsRegion is always generated");
        graph.AddRoot(ThreadStaticsRegion, "ThreadStaticsRegion is always generated");
        graph.AddRoot(EagerCctorTable, "EagerCctorTable is always generated");
        graph.AddRoot(TypeManagerIndirection, "TypeManagerIndirection is always generated");
        graph.AddRoot(FrozenSegmentRegion, "FrozenSegmentRegion is always generated");
        graph.AddRoot(InterfaceDispatchCellSection, "Interface dispatch cell section is always generated");
        graph.AddRoot(ModuleInitializerList, "Module initializer list is always generated");

        if (_inlinedThreadStatics.IsComputed())
        {
            graph.AddRoot(_inlinedThreadStatiscNode, "Inlined threadstatics are used if present");
            graph.AddRoot(TlsRoot, "Inlined threadstatics are used if present");
        }

        ReadyToRunHeader.Add(ReadyToRunSectionType.GCStaticRegion, GCStaticsRegion);
        ReadyToRunHeader.Add(ReadyToRunSectionType.ThreadStaticRegion, ThreadStaticsRegion);
        ReadyToRunHeader.Add(ReadyToRunSectionType.EagerCctor, EagerCctorTable);
        ReadyToRunHeader.Add(ReadyToRunSectionType.TypeManagerIndirection, TypeManagerIndirection);
        ReadyToRunHeader.Add(ReadyToRunSectionType.FrozenObjectRegion, FrozenSegmentRegion);
        ReadyToRunHeader.Add(ReadyToRunSectionType.ModuleInitializerList, ModuleInitializerList);

        var commonFixupsTableNode = new ExternalReferencesTableNode("CommonFixupsTable", this);
        InteropStubManager.AddToReadyToRunHeader(ReadyToRunHeader, this, commonFixupsTableNode);
        MetadataManager.AddToReadyToRunHeader(ReadyToRunHeader, this, commonFixupsTableNode);
        MetadataManager.AttachToDependencyGraph(graph);
        ReadyToRunHeader.Add(MetadataManager.BlobIdToReadyToRunSection(ReflectionMapBlob.CommonFixupsTable), commonFixupsTableNode);
    }
}

結合上面的代碼,我們的 PortableThreadPool 靜態類會記錄到根區域的 GCStaticsRegion 中,有了這些知識,接下來就是開挖了。

3. 使用 windbg 開挖

用 windbg 啟動生成好的 aot程序,接下來用 Example_21_8!S_P_CoreLib_System_Threading_PortableThreadPool::__GCSTATICS 找到類中的靜態字段。

0:007> dp Example_21_8!S_P_CoreLib_System_Threading_PortableThreadPool::__GCSTATICS L1
00007ff6`e4b7c5d0  000002a5`a4000468
0:007> dp 000002a5`a4000468+0x8 L1
000002a5`a4000470  000002a5`a6809ca0
0:007> dd 000002a5`a6809ca0+0x50 L1
000002a5`a6809cf0  0000000a
0:007> ? a
Evaluate expression: 10 = 00000000`0000000a

從上面的卦中可以清晰的看到,當前的CPU=10%。這里稍微解釋下 000002a5a4000468+0x8 是用來跳過vtable從而取到類實例,后面的 000002a5a6809ca0+0x50 是用來獲取 PortableThreadPool._cpuUtilization 字段的,布局參考如下:

0:012> !dumpobj /d 27bc100b288
Name:        System.Threading.PortableThreadPool
MethodTable: 00007ffc6c1aa6f8
EEClass:     00007ffc6c186b38
Tracked Type: false
Size:        512(0x200) bytes
File:        C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.8\System.Private.CoreLib.dll
Fields:
              MT    Field   Offset                 Type VT     Attr            Value Name
00007ffc6c031188  4000d42       50         System.Int32  1 instance                10 _cpuUtilization
00007ffc6c0548b0  4000d43       5c         System.Int16  1 instance               12 _minThreads
00007ffc6c0548b0  4000d44       5e         System.Int16  1 instance            32767 _maxThreads

三、總結

總的來說如果你的AOT使用默認的 WindowsThreadPool,那想獲取 cpu利用率基本上是無力回天,當然有達人知道的話可以告知下,如果切到默認的.NET線程池還是有的一拼,即使沒有 pdb 符號也可以根據_minThreads和_maxThreads的內容反向搜索。

責任編輯:武曉燕 來源: 一線碼農聊技術
相關推薦

2024-10-11 14:42:59

2023-04-04 09:22:50

LinuxCPU命令

2017-08-25 15:56:54

Linuxproc文件系統CPU利用率

2024-10-24 11:08:00

C#AOT泛型

2010-03-11 16:49:55

Linux CPU利用

2024-06-26 09:29:53

2011-03-17 15:16:38

2013-01-04 10:44:31

IBMdW

2019-03-05 15:53:40

Linux服務器CPU

2012-10-11 10:21:33

數據中心CPU利用率服務器效率

2019-08-28 06:58:06

Linux監控腳本Shell

2025-09-15 08:34:01

2010-03-15 15:01:37

2019-01-23 10:21:32

吞吐量響應時間CPU

2011-03-17 13:54:42

查詢參數SQL語句利用率

2021-02-03 09:26:49

數據中心基礎設施能源

2025-11-03 02:45:00

2015-09-07 11:54:25

云計算數據中心資源利用

2013-03-19 12:23:25

SDN網絡利用率網絡系統架構

2011-04-12 09:07:47

磁盤空間利用率虛擬化的隱藏成本
點贊
收藏

51CTO技術棧公眾號

日韩深夜影院| av福利精品| 亚洲黄色天堂| 国产小视频91| 看看黄色一级片| 97天天综合网| 国产女主播一区| 成人欧美一区二区三区在线观看| 久久艹免费视频| 色综合蜜月久久综合网| 亚洲国产三级网| 日本人69视频| 成人性生活视频| 亚洲男人的天堂av| 欧美日韩系列| 亚洲精品综合网| 少妇视频一区二区| 欧洲成人综合网| 亚洲国产精品成人综合| 亚洲xxxx在线| 成人黄色片在线观看| 国产一区亚洲| www日韩欧美| 9.1成人看片| 91麻豆精品激情在线观看最新| 色婷婷av一区二区三区软件| 欧美国产视频一区| 夜级特黄日本大片_在线| 99精品欧美一区二区三区小说| 91免费视频国产| 亚洲精品久久久久久久蜜桃| 91久久亚洲| 欧美裸体xxxx极品少妇| 五月婷婷六月香| 中文有码一区| 日韩精品一区二区三区第95| 亚洲日本久久久| japansex久久高清精品| 欧美日韩国产在线观看| 成人三级视频在线播放| 狠狠操一区二区三区| 亚洲男人的天堂av| 女女同性女同一区二区三区按摩| av基地在线| 欧美国产日本韩| 欧美三级网色| 色一情一乱一乱一区91av| 国产福利一区二区三区视频| 成人免费网视频| 伊人免费在线观看高清版| 久久成人一区| 欧洲成人在线视频| 成人免费毛片男人用品| 国产日韩欧美高清免费| 2025国产精品视频| 免费日韩一级片| 亚洲九九精品| 88xx成人精品| 久久中文字幕免费| 天堂精品中文字幕在线| 日本精品久久久| 免费无码国产精品| 三级成人在线视频| 国产精品久久久久久久久久东京 | 久久久精品tv| 欧美精品国产精品久久久| 亚洲三区在线播放| 久久久久国产精品麻豆ai换脸 | 亚洲丝袜自拍清纯另类| 制服诱惑一区| 手机在线免费av| 亚洲午夜免费视频| 国产极品在线视频| 日韩免费va| 欧美日韩一级片网站| 爱豆国产剧免费观看大全剧苏畅| 久久久久九九精品影院| 精品久久久久久久人人人人传媒 | 日本福利视频在线| 国产日韩电影| 欧美日韩国产一级片| 久久出品必属精品| 国内精品偷拍| 亚洲最新在线视频| 亚洲国产精品久| 国产日韩欧美| 91精品久久久久久久久久久久久 | 亚洲美女性视频| 永久免费av无码网站性色av| 天天综合亚洲| 午夜精品99久久免费| 丁香社区五月天| 日本亚洲视频| 国产主播精品| 69视频在线播放| 亚洲 国产 日韩 欧美| 激情文学综合丁香| 久久精品国产精品青草色艺| av在线免费观看网站| 一区二区三区色| 亚洲色成人一区二区三区小说| 激情久久一区二区| 亚洲国产成人精品久久| 国产主播av在线| 亚洲国产专区| 成人激情黄色网| 日本免费一区二区三区最新| 一区在线播放视频| 国模无码视频一区二区三区| 欧美aaaaaaaa| 亚洲精品中文字幕有码专区| 91插插插插插插| 日本欧美一区二区三区乱码| 99re在线播放| 1区2区3区在线观看| 欧美日韩国产在线| 少妇极品熟妇人妻无码| 久久国产中文字幕| 欧美诱惑福利视频| 国产综合无码一区二区色蜜蜜| 日本一区二区免费在线| 亚洲人精品午夜射精日韩| 999精品视频在线观看| 亚洲色图25p| 毛片视频网站在线观看| 国产福利91精品| 亚洲在线视频一区二区| 欧美大片免费高清观看| 欧美精品一区在线观看| www欧美com| 美国av一区二区| 欧美亚洲免费高清在线观看 | 成人免费在线视频观看| 国产免费视频传媒| 亚洲另类春色校园小说| 久久久中精品2020中文| www.爱爱.com| 亚洲免费观看高清完整版在线| 欧美日韩怡红院| 国产亚洲一区二区三区不卡| 97在线免费视频| 欧美一区二区在线观看视频| 亚洲美女精品一区| 色婷婷一区二区三区在线观看| 成人高清av| 国产精品福利在线观看| 日本五码在线| 91久久精品午夜一区二区| 精品国产无码在线观看| 国产精品日韩精品欧美精品| 久久99久久精品国产| 天堂8中文在线最新版在线| 亚洲电影免费观看高清完整版在线观看 | 女人喷潮完整视频| 噜噜噜天天躁狠狠躁夜夜精品| 久久久久国产精品一区| 高潮一区二区三区乱码| 五月婷婷综合在线| 国内精品久久99人妻无码| 国产亚洲欧洲| 日韩av一区二区三区美女毛片| 日韩新的三级电影| 国产亚洲视频中文字幕视频| 波多野结衣av无码| 国产精品乱人伦中文| www.桃色.com| 在线不卡视频| 欧美日韩精品不卡| av成人在线播放| 久久久久北条麻妃免费看| 国产三级漂亮女教师| 亚洲妇熟xx妇色黄| 欧美日韩亚洲一区二| 男女污污的视频| 久久久综合色| 99精品国产高清一区二区| 97人澡人人添人人爽欧美| 日韩精品一区二区三区第95| 中文 欧美 日韩| 亚洲日本成人在线观看| 超碰caoprom| 日韩精品亚洲一区| 黄黄视频在线观看| 高清精品xnxxcom| 国产精品18久久久久久麻辣| 麻豆av免费在线观看| 精品少妇一区二区三区视频免付费| 国产精品男女视频| 国产精品嫩草影院com| 国产黑丝在线视频| 性高湖久久久久久久久| 亚洲欧美电影在线观看| 成人av地址| 国产日本欧美在线观看 | 亚洲视频在线一区二区| 亚洲啪av永久无码精品放毛片| 久久久天天操| 最近免费观看高清韩国日本大全| 欧美a大片欧美片| 国产欧美中文字幕| 三妻四妾的电影电视剧在线观看 | 少妇愉情理伦三级| 成人午夜在线视频| 亚洲激情在线看| 国产偷自视频区视频一区二区| 爱爱爱视频网站| 九一成人免费视频| 成人综合色站| 欧美成人一二区| 456亚洲影院| 色女人在线视频| 在线一区二区日韩| 亚洲日本国产精品| 欧美一区二区性放荡片| 波多野结衣一区二区三区在线| 亚洲一区二区四区蜜桃| 亚洲色图27p| 久久久亚洲午夜电影| 亚洲精品激情视频| 国产99久久久久久免费看农村| 亚洲精品一二三四五区| 国产亚洲激情| 国产在线精品91| 国产精品hd| 国产av不卡一区二区| 成人久久综合| 欧美主播一区二区三区美女 久久精品人| 亚洲精品国产九九九| 91精品啪在线观看麻豆免费| 国产日韩另类视频一区| 欧美专区福利在线| 678在线观看视频| 欧美国产乱视频| 黄色视屏免费在线观看| 伊人伊成久久人综合网站| 天堂av在线免费观看| 精品免费国产一区二区三区四区| 国产精品视频在线观看免费| 欧美日韩精品高清| 亚洲天堂狠狠干| 欧美日韩精品一区二区三区四区| 精品久久久久久久久久久国产字幕 | 69堂免费精品视频在线播放| 琪琪第一精品导航| 色是在线视频| 欧美一级在线亚洲天堂| 蜜臀久久精品| 欧美洲成人男女午夜视频| 忘忧草在线日韩www影院| 91国内揄拍国内精品对白| 黄色漫画在线免费看| 97视频免费在线观看| 麻豆蜜桃在线观看| 欧美在线视频免费| 写真福利精品福利在线观看| 国产精品成人va在线观看| 日韩制服诱惑| 国产噜噜噜噜久久久久久久久| 国产原创一区| 成人信息集中地欧美| 亚洲精品不卡在线观看| 国产九色91| 亚洲人和日本人hd| 无遮挡亚洲一区| 午夜国产一区二区| 久久久久福利视频| 在线电影一区| 日韩视频免费在线播放| 久久精品国产一区二区三| 亚洲综合20p| 成人动漫在线一区| 中文字幕免费高清| 中文字幕一区二区三区在线不卡 | 中文字幕在线视频一区二区| 国产成人精品一区二区三区四区 | 日本一区二区三区四区在线视频| 色屁屁草草影院ccyy.com| 日韩理论片中文av| 日韩伦人妻无码| 在线视频中文字幕一区二区| 一区二区三区www污污污网站| 欧美一区二区成人| 视频二区在线| 久久久国产一区二区三区| 成人性生交大片免费看在线播放| 青青久久aⅴ北条麻妃| 亚瑟国产精品| 久久精品一二三区| 日产精品一区二区| av日韩一区二区三区| 蜜桃免费网站一区二区三区| 4438x全国最大成人| 久久精品一区蜜桃臀影院| 少妇被躁爽到高潮无码文| 欧美性xxxxxxxxx| a在线观看免费| 亚洲欧洲偷拍精品| 欧美1234区| 国产精品美女久久久免费| 精品国产午夜肉伦伦影院| 日韩av电影免费播放| 在线观看不卡| 尤物国产在线观看| 久久综合av免费| 欧美黑人一级片| 在线观看亚洲a| 熟妇人妻系列aⅴ无码专区友真希 熟妇人妻av无码一区二区三区 | 亚洲这里只有精品| 91视频免费观看| 欧美日韩免费一区二区| 欧美色区777第一页| 日韩一区二区三区在线观看视频| 最新亚洲国产精品| 一个人看的www视频在线免费观看| 97久久精品午夜一区二区| 成人区精品一区二区婷婷| 噜噜噜久久亚洲精品国产品麻豆| 国产精品自在在线| 亚洲色图100p| 91久久久免费一区二区| 内射无码专区久久亚洲| 久久久成人精品| 久久青草视频| 日本不卡一区二区三区视频| 99在线热播精品免费99热| 师生出轨h灌满了1v1| 中文字幕欧美一区| 一级黄色短视频| 在线观看精品国产视频| 搜成人激情视频| 免费成人在线观看av| 99亚洲视频| 成人h动漫精品一区| 亚洲成人福利片| 亚洲黄色精品视频| 九九九久久久久久| 久久九九精品视频| 久久久天堂国产精品| 国产一区二区不卡| 污污的视频在线免费观看| 777奇米成人网| a视频在线播放| 亚洲综合视频1区| 亚洲午夜av| 中文字幕乱视频| 五月婷婷欧美视频| 污污的视频网站在线观看| 91精品国产91久久久久久最新| 成人中文字幕视频| 人人妻人人做人人爽| av在线一区二区三区| 日本少妇xxxx动漫| 亚洲国产欧美在线成人app| 欲香欲色天天天综合和网| 久久久影院一区二区三区 | 欧美一级大片在线观看| 视频小说一区二区| 国产性xxxx18免费观看视频| 久久综合国产精品| 中文字幕乱码人妻二区三区| 一本色道久久88精品综合| 亚洲ww精品| 大胆欧美熟妇xx| 97精品久久久午夜一区二区三区| 特一级黄色大片| 国产午夜精品美女视频明星a级| 91tv亚洲精品香蕉国产一区| 一本一道久久a久久综合精品| 国产一二精品视频| 国产亚洲成人av| 亚洲男人天堂视频| 久久人体av| 波多野结衣av一区二区全免费观看| 成人午夜精品一区二区三区| 久久久久久久久久久影院| 中文日韩电影网站| 亚洲精品在线播放| 国产日韩一区二区在线| 欧美国产1区2区| 国产黄色大片网站| 2021国产精品视频| 午夜精品一区二区三区国产 | 久久精品国产精品亚洲色婷婷| 久久久久久97三级| 国产精品欧美久久久久天天影视| 久久久噜噜噜久久| 欧美日韩国产传媒| 国产精九九网站漫画| 色视频欧美一区二区三区| 成人国产免费电影| 日本免费一区二区三区| 国产盗摄女厕一区二区三区 | 久久亚洲资源| 欧美在线一二三区| 成人综合在线视频| 五月天中文字幕| 久久乐国产精品| 日韩欧美视频专区| 欧美色图亚洲激情| 欧美一级一级性生活免费录像|