精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

人妻丰满熟妇aⅴ无码| 久操网在线观看| 国产一区二区三区黄片| 欧美日韩免费| 亚洲人成绝费网站色www| 色www免费视频| 92久久精品| 国产精品美女久久久久久久 | 一本久道久久综合狠狠爱亚洲精品| 91美女精品网站| 99视频一区| 久久精品国产电影| 懂色av粉嫩av蜜乳av| 亚洲精品66| 精品久久久久久中文字幕一区奶水| 亚洲精品日韩在线观看| 成人午夜精品福利免费| 开心九九激情九九欧美日韩精美视频电影 | 国产精品大陆在线观看| 欧美日韩在线观看成人| 久操精品在线| 欧美精品一区二区三区蜜桃| 日本黄色的视频| www.成人爱| 亚洲成人tv网| 男人天堂网站在线| 在线视频1区2区| 久久久午夜精品理论片中文字幕| 成人免费视频观看视频| 国产又黄又粗又猛又爽| 在线亚洲激情| 欧美精品www| 影音先锋男人资源在线观看| 精品一区免费| 日韩久久午夜影院| 性高潮免费视频| 亚洲视频三区| 91精品国产一区二区三区蜜臀| 亚洲一区二区蜜桃| 久久毛片亚洲| 欧美日韩精品在线观看| 丰满少妇大力进入| 欧美午夜大胆人体| 亚洲综合视频网| 久久人妻无码一区二区| 精品国产99久久久久久| 国产精品国产自产拍高清av王其| 欧美重口乱码一区二区| 精品av中文字幕在线毛片 | 久久久成人网| 国产成+人+综合+亚洲欧美丁香花| 欧美一二三区视频| 在线亚洲免费| 日本精品性网站在线观看| 国产成人无码精品亚洲 | 亚洲色成人一区二区三区小说| 福利写真视频网站在线| 亚洲国产精品尤物yw在线观看| 麻豆传媒网站在线观看| av网站大全在线| 一区二区三区视频在线看| 18视频在线观看娇喘| av文字幕在线观看| 亚洲六月丁香色婷婷综合久久| japanese在线视频| 亚洲资源一区| 亚瑟在线精品视频| 精品99在线视频| 成人在线视频免费| 欧美精品三级日韩久久| 日本人dh亚洲人ⅹxx| 999国产精品一区| 日韩第一页在线| 亚洲综合色一区| 日韩欧美午夜| 欧美第一淫aaasss性| 日韩网红少妇无码视频香港| 久久成人国产| 国产欧美亚洲视频| 国产wwwwwww| 99国产精品久久久久久久久久| 欧美一区二区三区成人久久片| 搞黄视频免费在线观看| 亚洲精品亚洲人成人网| 成人综合视频在线| 久久av影院| 亚洲成人1234| 久久久国产一级片| 一区在线视频观看| 国产精品黄色影片导航在线观看| 国产精品无码免费播放| bt欧美亚洲午夜电影天堂| 欧洲精品久久| 激情网站在线| 欧美丝袜丝交足nylons图片| 宇都宫紫苑在线播放| 国产毛片久久久| 在线播放精品一区二区三区| 欧美精品入口蜜桃| 天堂av在线一区| 不卡视频一区二区| 爱久久·www| 亚洲成人精品一区二区| 亚洲黄色av网址| 久久综合另类图片小说| y97精品国产97久久久久久| 男女视频免费看| 国产一区在线不卡| 日本精品二区| ****av在线网毛片| 欧美精品v国产精品v日韩精品| 91av在线免费| 国产精品九九| 91天堂在线视频| 国产视频三级在线观看播放| 亚洲国产美国国产综合一区二区| 欧美美女一级片| 伊人久久大香线蕉av不卡| 久久6免费高清热精品| 91女人18毛片水多国产| 久久久久久久久99精品| 免费观看美女裸体网站| 免费看一区二区三区| 在线观看欧美日韩国产| www.com国产| 波多野结衣91| 男人添女人下部视频免费| 亚洲a成人v| 伊人久久免费视频| 日日摸天天添天天添破| av电影天堂一区二区在线| 男人天堂成人网| 国产电影一区二区| 日韩中文字幕在线精品| 欧美一级做a爰片免费视频| 久久综合九色综合欧美亚洲| 欧美大片在线播放| av男人一区| 欧美激情性做爰免费视频| av网站在线免费看| 亚洲免费观看高清| 性鲍视频在线观看| 久久精品亚洲人成影院| 成人福利网站在线观看| 免费网站成人| 在线观看视频91| 天天躁日日躁aaaxxⅹ| 久久视频一区| 色就是色欧美| 日本一区二区三区中文字幕| 久久精品91久久香蕉加勒比| 亚洲天堂avav| 亚洲男人都懂的| 国产在线视频三区| 国一区二区在线观看| 国产98在线|日韩| 国产精品xx| 亚洲欧美视频在线| 中文天堂在线播放| 亚洲少妇屁股交4| 潘金莲一级淫片aaaaa| 亚洲午夜黄色| 久久综合九色综合网站| 亚洲精品国产嫩草在线观看| 中文字幕国内精品| 国产精品区在线观看| 一区二区三区蜜桃网| 99re这里只有| 日韩国产欧美在线观看| 亚洲一区三区电影在线观看| av在线亚洲一区| 欧美激情综合色综合啪啪五月| 日本黄色三级视频| 一本到不卡精品视频在线观看| 少妇愉情理伦三级| 国产一区二区不卡| 欧美三级在线观看视频| 欧美裸体在线版观看完整版| 成人在线中文字幕| av资源网在线播放| 亚洲色图第三页| 国产熟女一区二区三区五月婷| 亚洲一区在线观看免费观看电影高清 | 91免费精品国自产拍在线不卡| 韩国日本在线视频| 亚洲乱码电影| 久久精品国产一区二区三区日韩 | 日本高清在线观看| 亚洲欧美成人精品| 国产精品伦一区二区三区| 婷婷夜色潮精品综合在线| 第一次破处视频| 国产91在线|亚洲| 青青草av网站| 在线国产精品一区| 亚洲欧美日韩在线综合| 成人在线视频你懂的| 国产精品免费久久久久久| 男插女视频久久久| 中文字幕国产亚洲| 污视频网站在线播放| 在线成人av网站| 色老头在线视频| 午夜精品福利一区二区三区av| 精品人体无码一区二区三区| 91在线视频网址| 国产伦精品一区二区三区妓女下载 | 中文字幕一区三区| 国产又黄又粗又猛又爽的视频| 狠狠狠色丁香婷婷综合久久五月| 缅甸午夜性猛交xxxx| 911久久香蕉国产线看观看| 欧美午夜精品理论片a级大开眼界 欧美午夜精品久久久久免费视 | 午夜福利一区二区三区| 91精品国产高清一区二区三区 | 国产午夜精品理论片在线| 99国产精品久久久久久久久久| 色姑娘综合天天| 免费观看日韩电影| 成人在线看视频| 亚洲国产裸拍裸体视频在线观看乱了中文| 亚洲日本无吗高清不卡| 亚洲精品亚洲人成在线观看| 国产乱码精品一区二区三区卡| 外国成人毛片| 国产精品亚洲欧美导航| 精品国产免费人成网站| 91精品国产色综合久久不卡98| 特级毛片在线| 不卡av在线网站| 浪潮av一区| 精品国产一区二区三区久久久狼 | 精品毛片在线观看| 欧美日本国产视频| 中文字幕av在线免费观看| 色综合久久99| 成年人视频免费| 日韩欧美在线国产| 青青草免费观看视频| 好吊成人免视频| 天天操天天摸天天干| 激情成人在线视频| 日韩成人一区二区三区| 五月婷婷激情综合| 国产稀缺真实呦乱在线| 天天综合色天天综合色h| 国产精品suv一区二区| 香港成人在线视频| 日韩美女视频网站| 日韩欧美一区二区三区| 波多野结衣一二区| 欧美系列亚洲系列| 91久久久久久久久久久久| 这里只有精品电影| 国内精品久久久久久久久久久| 欧美变态tickle挠乳网站| 亚洲精品综合网| 亚洲激情视频在线| 久草在线网址| www.日韩不卡电影av| 先锋影音在线资源站91| 久久久爽爽爽美女图片| 中文字幕21页在线看| 国产精品av免费在线观看| 日韩伦理一区二区| av在线亚洲男人的天堂| 六月丁香久久丫| 日本一区二区三区视频免费看| 欧美高清视频手机在在线| 欧美一级免费在线观看| 亚洲日韩视频| 天天干在线影院| 国产精品一级片在线观看| 星空大象在线观看免费播放| 久久久久久久久岛国免费| 中国一级片在线观看| 亚洲国产人成综合网站| 你懂的国产在线| 91精品国产乱码久久蜜臀| 免费av网站观看| 一区二区亚洲精品国产| www在线视频| 日韩av电影在线网| 国产精品亚洲四区在线观看 | 亚洲人成色777777老人头| 在线成人激情视频| 啦啦啦中文在线观看日本| 国产精品h片在线播放| 欧美第一在线视频| 久久艳妇乳肉豪妇荡乳av| 日韩综合在线| 免费av观看网址| 卡一卡二国产精品| 免费的av网站| 亚洲欧洲性图库| 精品免费囯产一区二区三区 | 国产精品视频白浆免费视频| 一区二区三区在线资源| 欧美亚洲爱爱另类综合| 欧美激情四色| 香港日本韩国三级网站| av在线不卡网| 超碰手机在线观看| 欧洲一区二区三区在线| 人人妻人人澡人人爽人人欧美一区 | 成人在线精品视频| 影视先锋久久| 麻豆tv在线播放| 国产精品一区二区三区四区| 中文字幕人妻一区二区三区在线视频| 亚洲曰韩产成在线| 亚洲字幕av一区二区三区四区| 日韩av中文字幕在线免费观看 | 91成品人片a无限观看| 久久视频免费| 亚洲一区二区三区免费观看| 久久aⅴ国产紧身牛仔裤| 亚洲麻豆一区二区三区| 日韩美女视频一区二区| 这里只有精品国产| 亚洲免费电影一区| 爱搞国产精品| 成人一区二区三区四区| 影音先锋成人在线电影| 在线免费观看视频黄| 国产亚洲欧美中文| 五月天婷婷综合网| 欧美精品一区视频| 日韩伦理电影网站| 亚洲一区亚洲二区| 国产精品成人a在线观看| 在线观看亚洲色图| 亚洲国产精品ⅴa在线观看| 黄色片中文字幕| 亚洲精品视频免费| 色多多在线观看| 久久国产精品精品国产色婷婷 | 亚洲最大成人在线观看| 国产女主播视频一区二区| 国产一区免费看| 亚洲欧洲日本专区| 日韩不卡免费高清视频| 日本不卡一区二区三区在线观看 | 国产精品毛片a∨一区二区三区|国| 亚洲另类av| 无码少妇一区二区三区芒果| 99精品热视频| 精品免费囯产一区二区三区| 国产亚洲精品激情久久| 成人h在线观看| 一区二区三区四区视频在线观看| 美女视频一区二区三区| www深夜成人a√在线| 日韩一二三四区| www在线观看黄色| 麻豆成人小视频| 日韩国产精品91| 国产中文av在线| 欧美白人最猛性xxxxx69交| 成全电影大全在线观看| 久久综合九色欧美狠狠| 奇米色一区二区三区四区| 九九热视频在线免费观看| 精品久久久久久久久久久久包黑料 | 亚洲欧美另类综合偷拍| 国产成人免费看一级大黄| 97精品国产97久久久久久免费| 伊人久久大香线蕉综合网站| 国产喷水theporn| 一区二区成人在线| 五十路在线观看| 国产精品视频地址| 一区二区三区四区电影| 亚洲视频在线播放免费| 色一区在线观看| 免费a级毛片在线播放| 国产高清自拍99| 老司机午夜精品视频| 老司机福利在线观看| 欧美www视频| 四虎4545www国产精品| www国产免费| 久久久高清一区二区三区| 国产精品欧美久久久久天天影视| 性色av一区二区三区在线观看| 日本一区二区高清不卡| 久久精品aⅴ无码中文字字幕重口| 色哟哟在线观看一区二区三区| 国产剧情在线| 欧美主播一区二区三区美女 久久精品人 | 国产无色aaa| 欧美日韩午夜视频在线观看| 在线免费观看黄| 精品国产aⅴ麻豆| 久久99久久99| jizz国产在线观看| 欧美激情精品久久久久久| 日本欧美国产| 中文字幕一区二区久久人妻网站| 在线播放中文一区|