日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > asp.net >内容正文

asp.net

如何在 .NET 程序万种死法中有效的生成 Dump (上)

發(fā)布時(shí)間:2023/12/4 asp.net 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何在 .NET 程序万种死法中有效的生成 Dump (上) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一:背景

相信很多人都知道通過(guò)?任務(wù)管理器?抓取dump,雖然簡(jiǎn)單粗暴,但無(wú)法滿足程序的無(wú)數(shù)種死法,比如:

  • 內(nèi)存膨脹,程序爆炸

  • CPU爆高,程序累死

  • 應(yīng)用無(wú)響應(yīng),用戶氣死

  • 意外退出,和人生一樣

既然手工太弱雞,那有什么好的工具呢?除了 adplus,本文推薦一款神器?procdump, 下載地址:https://docs.microsoft.com/zh-cn/sysinternals/downloads/procdump ,還能支持 linux ????????????,具體怎么安裝就不細(xì)說(shuō)了。

二:內(nèi)存膨脹,程序爆炸

內(nèi)存膨脹?這種情況我相信很有朋友都遇到過(guò),我見(jiàn)過(guò)最多的案例就是用了小緩存 static,然后有意無(wú)意的忘記釋放,導(dǎo)致無(wú)限堆積終爆炸,那這種怎么用 procdump 去抓呢?

為了方便演示,我先寫(xiě)一個(gè)無(wú)限分配內(nèi)存的例子。

static?void?Main(string[]?args){List<string>?list?=?new?List<string>();for?(int?i?=?0;?i?<?int.MaxValue;?i++){list.Add(string.Join(",",?Enumerable.Range(0,?10000)));}Console.ReadLine();}

將程序跑起來(lái)后,設(shè)置 procdump 在內(nèi)存超過(guò) 1G 的時(shí)候自動(dòng)抓取全內(nèi)存 dump,使用如下命令.

C:\Windows\system32>procdump??ConsoleApp2?-m?1024?-ma?E:\net5\ConsoleApp1\ConsoleApp2\bin\DebugProcDump?v10.0?-?Sysinternals?process?dump?utility Copyright?(C)?2009-2020?Mark?Russinovich?and?Andrew?Richards Sysinternals?-?www.sysinternals.comProcess:???????????????ConsoleApp2.exe?(24112) Process?image:?????????E:\net5\ConsoleApp1\ConsoleApp2\bin\Debug\ConsoleApp2.exe CPU?threshold:?????????n/a Performance?counter:???n/a Commit?threshold:??????>=?1024?MB Threshold?seconds:?????10 Hung?window?check:?????Disabled Log?debug?strings:?????Disabled Exception?monitor:?????Disabled Exception?filter:??????[Includes]*[Excludes] Terminate?monitor:?????Disabled Cloning?type:??????????Disabled Concurrent?limit:??????n/a Avoid?outage:??????????n/a Number?of?dumps:???????1 Dump?folder:???????????E:\net5\ConsoleApp1\ConsoleApp2\bin\Debug\ Dump?filename/mask:????PROCESSNAME_YYMMDD_HHMMSS Queue?to?WER:??????????Disabled Kill?after?dump:???????DisabledPress?Ctrl-C?to?end?monitoring?without?terminating?the?process.[21:23:43]?Commit:????1087Mb [21:23:43]?Dump?1?initiated:?E:\net5\ConsoleApp1\ConsoleApp2\bin\Debug\ConsoleApp2.exe_210323_212343.dmp [21:23:43]?Dump?1?writing:?Estimated?dump?file?size?is?1179?MB. [21:23:44]?Dump?1?complete:?1179?MB?written?in?1.3?seconds [21:23:44]?Dump?count?reached.

從最后五行可以看出,當(dāng)內(nèi)存達(dá)到?1087M?的時(shí)候自動(dòng)生成了 dump 文件,接下來(lái)用 windbg 看一看。

  • 查看當(dāng)前 process 的內(nèi)存占用量,使用?!address -summary?即可

0:000>?!address?-summaryMapping?file?p?regions... Mapping?module?regions... Mapping?PEB?regions... Mapping?TEB?and?stack?regions... Mapping?heap?regions... Mapping?page?heap?regions... Mapping?other?regions... Mapping?stack?trace?database?regions... Mapping?activation?context?regions...---?Usage?Summary?----------------?RgnCount?-----------?Total?Size?--------?%ofBusy?%ofTotal Free?????????????????????????????????????63??????????b30b4000?(???2.798?GB)???????????69.94% <unknown>???????????????????????????????228??????????48547000?(???1.130?GB)??93.99%???28.25% Image???????????????????????????????????210???????????4115000?(??65.082?MB)???5.29%????1.59% Stack????????????????????????????????????21????????????700000?(???7.000?MB)???0.57%????0.17% Heap?????????????????????????????????????12????????????170000?(???1.438?MB)???0.12%????0.04% Other?????????????????????????????????????7?????????????5a000?(?360.000?kB)???0.03%????0.01% TEB???????????????????????????????????????7?????????????13000?(??76.000?kB)???0.01%????0.00% PEB???????????????????????????????????????1??????????????3000?(??12.000?kB)???0.00%????0.00%---?Type?Summary?(for?busy)?------?RgnCount?-----------?Total?Size?--------?%ofBusy?%ofTotal MEM_PRIVATE?????????????????????????????250??????????47121000?(???1.110?GB)??92.36%???27.76% MEM_IMAGE???????????????????????????????217???????????411e000?(??65.117?MB)???5.29%????1.59% MEM_MAPPED???????????????????????????????19???????????1cfd000?(??28.988?MB)???2.35%????0.71%---?State?Summary?----------------?RgnCount?-----------?Total?Size?--------?%ofBusy?%ofTotal MEM_FREE?????????????????????????????????63??????????b30b4000?(???2.798?GB)???????????69.94% MEM_COMMIT??????????????????????????????357??????????47f12000?(???1.124?GB)??93.49%???28.10% MEM_RESERVE?????????????????????????????129???????????502a000?(??80.164?MB)???6.51%????1.96%---?Protect?Summary?(for?commit)?-?RgnCount?-----------?Total?Size?--------?%ofBusy?%ofTotal PAGE_READWRITE??????????????????????????177??????????437d5000?(???1.055?GB)??87.70%???26.36% PAGE_EXECUTE_READ????????????????????????35???????????33c7000?(??51.777?MB)???4.21%????1.26% PAGE_READONLY????????????????????????????90????????????c41000?(??12.254?MB)???1.00%????0.30% PAGE_WRITECOPY???????????????????????????34????????????70b000?(???7.043?MB)???0.57%????0.17% PAGE_READWRITE|PAGE_GUARD????????????????14?????????????23000?(?140.000?kB)???0.01%????0.00% PAGE_EXECUTE_READWRITE????????????????????7??????????????7000?(??28.000?kB)???0.00%????0.00%---?Largest?Region?by?Usage?-----------?Base?Address?--------?Region?Size?---------- Free????????????????????????????????????????80010000??????????7f130000?(???1.986?GB) <unknown>???????????????????????????????????438e1000???????????200f000?(??32.059?MB) Image???????????????????????????????????????660e0000????????????f55000?(??15.332?MB) Stack?????????????????????????????????????????e00000?????????????fd000?(1012.000?kB) Heap??????????????????????????????????????????c97000?????????????98000?(?608.000?kB) Other???????????????????????????????????????ff2c0000?????????????33000?(?204.000?kB) TEB???????????????????????????????????????????990000??????????????3000?(??12.000?kB) PEB???????????????????????????????????????????98d000??????????????3000?(??12.000?kB)

看到上面?PAGE_READWRITE?行的?(1.055 GB)?嗎?和剛才 Console 中的 1087M 遙相呼應(yīng),沒(méi)毛病。

  • 尋找大對(duì)象,在托管堆中使用?!dumpheap -stat -min 1024?即可

||0:0:000>?!dumpheap?-stat?-min?1024 Statistics:MT????Count????TotalSize?Class?Name 65d42788????????2????????13044?System.Object[] 65d42d74????????2????????98328?System.String[] 65d42c60???????73??????1082988?System.Char[] 65d424e4????11452???1119913984?System.String

從輸出的最后一行可以看出,System.String?有1w多個(gè),接下來(lái)可以增加 ?-type?屬性篩選出?>10k?的字符串。

0:000>?!dumpheap?-type?System.String?-min?10240Address???????MT?????Size 03c75568?65d424e4????97792????? 03c8d378?65d424e4????97792???? 4a855060?65d424e4????97792?????Statistics:MT????Count????TotalSize?Class?Name 65d424e4????11452???1119913984?System.String Total?11452?objects0:000>?!gcroot?4a855060 Thread?36e4: ***?WARNING:?Unable?to?verify?checksum?for?ConsoleApp2.exe00b3f358?012108d1?ConsoleApp2.Program.Main(System.String[])?[E:\net5\ConsoleApp1\ConsoleApp2\Program.cs?@?18]ebp+18:?00b3f370->??02c71fd8?System.Collections.Generic.List`1[[System.String,?mscorlib]]->??02cce2ec?System.String[]->??4a855060?System.StringFound?1?unique?roots?(run?'!GCRoot?-all'?to?see?all?roots).

從最后的?!gcroot?看,確實(shí)是被?Program.cs:18?行的 List 所持有,到此水落石出。

三:CPU爆高,程序累死

說(shuō)起CPU爆高的案例,我發(fā)現(xiàn)更多的是在?非托管堆?上,比如GC回收,爭(zhēng)搶鎖等,很少有人能傻到在?托管層?上把cpu搞起來(lái)。

對(duì)了,分析CPU 爆高有一個(gè)小技巧,那就是連續(xù)抓 dump 快照,看兩個(gè) dump 中的線程運(yùn)行情況,這時(shí)候就非常適合 procdump,先來(lái)看測(cè)試代碼。

class?Program{static?void?Main(string[]?args){Parallel.For(0,?int.MaxValue,?(i)?=>{while?(true){}});Console.ReadLine();}}

現(xiàn)在我設(shè)定?連續(xù) 5s 內(nèi) CPU 超過(guò) 70% 抓取 dump,直到 2 個(gè)為止?。

C:\Windows\system32>procdump??ConsoleApp2?-s?5?-n?2?-c?70?E:\net5\ConsoleApp1\ConsoleApp2\bin\DebugProcDump?v10.0?-?Sysinternals?process?dump?utility Copyright?(C)?2009-2020?Mark?Russinovich?and?Andrew?Richards Sysinternals?-?www.sysinternals.comProcess:???????????????ConsoleApp2.exe?(22152) Process?image:?????????E:\net5\ConsoleApp1\ConsoleApp2\bin\Debug\ConsoleApp2.exe CPU?threshold:?????????>=?70%?of?system Performance?counter:???n/a Commit?threshold:??????n/a Threshold?seconds:?????5 Hung?window?check:?????Disabled Log?debug?strings:?????Disabled Exception?monitor:?????Disabled Exception?filter:??????[Includes]*[Excludes] Terminate?monitor:?????Disabled Cloning?type:??????????Disabled Concurrent?limit:??????n/a Avoid?outage:??????????n/a Number?of?dumps:???????2 Dump?folder:???????????E:\net5\ConsoleApp1\ConsoleApp2\bin\Debug\ Dump?filename/mask:????PROCESSNAME_YYMMDD_HHMMSS Queue?to?WER:??????????Disabled Kill?after?dump:???????DisabledPress?Ctrl-C?to?end?monitoring?without?terminating?the?process.[22:25:47]?CPU:?95%?1s [22:25:48]?CPU:?100%?2s [22:25:50]?CPU:?96%?3s [22:25:51]?CPU:?98%?4s [22:25:52]?CPU:?99%?5s?(Trigger) [22:25:53]?Dump?1?initiated:?E:\net5\ConsoleApp1\ConsoleApp2\bin\Debug\ConsoleApp2.exe_210323_222553.dmp [22:25:54]?Dump?1?complete:?5?MB?written?in?0.3?seconds [22:25:56]?CPU:?88%?1s [22:25:58]?CPU:?93%?2s [22:26:00]?CPU:?89%?3s [22:26:02]?CPU:?89%?4s [22:26:04]?CPU:?95%?5s?(Trigger) [22:26:05]?Dump?2?initiated:?E:\net5\ConsoleApp1\ConsoleApp2\bin\Debug\ConsoleApp2.exe_210323_222605.dmp [22:26:06]?Dump?2?complete:?5?MB?written?in?0.4?seconds [22:26:07]?Dump?count?reached.

從最后輸出中可以看到,連續(xù)?5s?CPU 超過(guò)了 70% 抓取了 dump,總共來(lái)了2個(gè)。

現(xiàn)在 dump 有了,接下來(lái)用兩個(gè) windbg 實(shí)例打開(kāi),驗(yàn)證下 dump 的生成時(shí)間,如下圖所示:

從圖中可以看到,兩個(gè) dump 生成時(shí)間相隔 12s,而且通過(guò)?!runaway?發(fā)現(xiàn)下面的線程:

  • 14:2cb8

  • 19:3f8c

  • ...

都運(yùn)行了長(zhǎng)達(dá) 10s ,這說(shuō)明什么?說(shuō)明這二個(gè)線程應(yīng)該在某個(gè)地方死循環(huán)了。。。對(duì)吧。。。

切到 14 號(hào)線程通過(guò)?!clrstack?看調(diào)用堆棧即可,都是死在?ConsoleApp2.Program+c.b__0_0(Int32)?這里出不來(lái)。。。

四:總結(jié)

感覺(jué)篇幅有點(diǎn)長(zhǎng)了,就先說(shuō)到這里吧,有興趣的話,可以把 procdump 拉下來(lái)玩一玩 ????。

END

工作中的你,是否已遇到 ...?

1. CPU爆高

2. 內(nèi)存暴漲

3. 資源泄漏

4. 崩潰死鎖

5. 程序呆滯

等緊急事件,全公司都指望著你能解決...? 危難時(shí)刻才能展現(xiàn)你的技術(shù)價(jià)值,作為專注于.NET高級(jí)調(diào)試的技術(shù)博主,歡迎微信搜索: 一線碼農(nóng)聊技術(shù),免費(fèi)協(xié)助你分析Dump文件,希望我能將你的踩坑經(jīng)驗(yàn)分享給更多的人。

總結(jié)

以上是生活随笔為你收集整理的如何在 .NET 程序万种死法中有效的生成 Dump (上)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。