成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

記一次 .NET 醫(yī)療布草 API 程序 內(nèi)存暴漲分析

存儲 存儲軟件
我在年前寫過一篇關(guān)于CPU爆高的分析文章 再記一次 應(yīng)用服務(wù)器 CPU 暴高事故分析 ,當(dāng)時是給同濟(jì)做項(xiàng)目升級,看過那篇文章的朋友應(yīng)該知道,最后的結(jié)論是運(yùn)維人員錯誤的將 IIS 應(yīng)用程序池設(shè)成 32bit 導(dǎo)致了事故的發(fā)生,這篇算是后續(xù),拖了好久才續(xù)上哈。

[[396727]]

本文轉(zhuǎn)載自微信公眾號「一線碼農(nóng)聊技術(shù)」,作者一線碼農(nóng)聊技術(shù)。轉(zhuǎn)載本文請聯(lián)系一線碼農(nóng)聊技術(shù)公眾號。

一:背景

1. 講故事

我在年前寫過一篇關(guān)于CPU爆高的分析文章 再記一次 應(yīng)用服務(wù)器 CPU 暴高事故分析 ,當(dāng)時是給同濟(jì)做項(xiàng)目升級,看過那篇文章的朋友應(yīng)該知道,最后的結(jié)論是運(yùn)維人員錯誤的將 IIS 應(yīng)用程序池設(shè)成 32bit 導(dǎo)致了事故的發(fā)生,這篇算是后續(xù),拖了好久才續(xù)上哈。

猶記得那些天老板天天找我們幾個人開會,大概老板是在傳導(dǎo)甲方給過來的壓力,人倒霉就是這樣,你說 CPU 爆高可怕吧,我硬是給摁下去了,好了,Memory 又爆高了,尼瑪我又給摁下去了,接著數(shù)據(jù)庫死鎖又來了,你能體會到這種壓力嗎??? 就像我在朋友圈發(fā)的那樣,程序再不跑我就要跑了。

[[396728]]

所以有時候敬敬風(fēng)水還是很有必要的,有點(diǎn)扯遠(yuǎn)了哈,這篇我們來看看程序的內(nèi)存暴漲如何去排查,為了讓你更有興趣,來一張運(yùn)維發(fā)的內(nèi)存監(jiān)控圖。

從圖中可以看出,9點(diǎn)開始內(nèi)存直線暴漲,絕對驚心動魄,要是我的小諾安這樣暴漲就好了,接下來 windbg 說話。

二:windbg 分析

1. 說一下思路

內(nèi)存暴漲了,最怕的就是 非托管層 出了問題,它的排查難度相比 托管層 要難10倍以上,所以遇到這類問題,先祈禱一下吧,gc堆也罷,loader堆也不怕,所以先看看是否 進(jìn)程內(nèi)存 ≈ gc堆內(nèi)存 ?

2. 排查托管還是非托管

排查方式也很簡單,通過 !address -summary 看看進(jìn)程的已提交內(nèi)存,如下輸出:

  1. 0:000> !address -summary 
  2.  
  3. --- State Summary ---------------- RgnCount ----------- Total Size -------- %ofBusy %ofTotal 
  4. MEM_FREE                                261      7fb`4b151000 (   7.982 TB)           99.77% 
  5. MEM_RESERVE                             278        2`6aafc000 (   9.667 GB)  51.35%    0.12% 
  6. MEM_COMMIT                             2199        2`4a3a3000 (   9.160 GB)  48.65%    0.11% 

可以看到已提交內(nèi)存是 9.1G,接下來看下 gc 堆的大小,使用 !eeheap -gc 即可。

  1. 0:000> !eeheap -gc 
  2. Number of GC Heaps: 8 
  3. ------------------------------ 
  4. Heap 0 (0000000002607740) 
  5. generation 0 starts at 0x00000001aaaa5500 
  6. generation 1 starts at 0x00000001aa3fd070 
  7. generation 2 starts at 0x0000000180021000 
  8. Heap 7 (0000000002713b40) 
  9. generation 0 starts at 0x000000053b3a2c28 
  10. generation 1 starts at 0x000000053a3fa770 
  11. generation 2 starts at 0x0000000500021000 
  12.  
  13. ------------------------------ 
  14. GC Heap Size:            Size: 0x1fdfe58c8 (8556271816) bytes. 

從最后一行輸出中可以看到當(dāng)前的占用是 8556271816 / 1024 /1024 /1024 = 7.9G ,太幸運(yùn)了,果然是托管層出了問題,gc 上有大塊臟東西,這下有救了 。

3. 查看托管堆

知道托管堆出了問題后,接下來就可以用 !dumpheap -stat 去gc堆上翻一翻。

  1. 0:000> !dumpheap -stat 
  2. Statistics
  3.               MT    Count    TotalSize Class Name 
  4. 000007fef7b5c308    32867       788808 System.DateTime 
  5. 000007fef7b5e598    33049       793176 System.Boolean 
  6. 000007feec7301f8    30430      1217200 System.Web.HttpResponseUnmanagedBufferElement 
  7. 000007fef7b56020     2931      3130928 System.Object[] 
  8. 000007fef7b580f8   219398      5265552 System.Int32 
  9. 000007fe9a0c5428    46423      7799064 xxx.Laundry.Entities.V_InvoiceInfo 
  10. 000007fef7b59638   164418      7892064 System.Text.StringBuilder 
  11. 000007fef7b56980   164713     10059852 System.Char[] 
  12. 000007fef7b5a278     7351     26037217 System.Byte[] 
  13. 000007fe9a0d8758       35     28326856 xxx.Laundry.Entities.V_ClothesTagInfo[] 
  14. 0000000002536f50    76837     77016088      Free 
  15. 000007fe9a327ab0    46534    312964608 xxx.Laundry.Entities.V_InvoiceClothesInfo[] 
  16. 000007fe9a0c4868  2068912    397231104 xxx.Laundry.Entities.V_ClothesTagInfo 
  17. 000007fef7b55b70 98986851   3483764540 System.String 
  18. 000007fe9a10ef80 23998759   3839801440 xxx.Laundry.Entities.V_InvoiceClothesInfo 
  19. Total 126039641 objects 

我去,托管堆上的 xxx.Laundry.Entities.V_InvoiceClothesInfo 對象居然高達(dá) 2399w ,占了大概 3.6G,這還不算其附屬對象,對了,如果直接用 !dumpheap -mt xxx 輸出 address 的話,很難進(jìn)行UI中止,所以這里有一個小技巧,用 range 來限定一下,如下代碼所示:

  1. 0:000> !dumpheap -mt 000007fe9a10ef80 0 0000000180027b30 
  2.          Address               MT     Size 
  3. 0000000180027800 000007fe9a10ef80      160      
  4. 0000000180027910 000007fe9a10ef80      160      
  5. 0000000180027a20 000007fe9a10ef80      160      
  6. 0000000180027b30 000007fe9a10ef80      160      
  7.  
  8. Statistics
  9.               MT    Count    TotalSize Class Name 
  10. 000007fe9a10ef80        4          640 xxx.Laundry.Entities.V_InvoiceClothesInfo 
  11. Total 4 objects 

4. 查找引用根

接下來用 !gcroot 隨便找一個 address 查看它的引用鏈,看看它到底被誰引用著?

  1. 0:000> !gcroot 0000000180027800 
  2. HandleTable: 
  3.     00000000013715e8 (pinned handle) 
  4.     -> 000000058003c038 System.Object[] 
  5.     -> 00000004800238a0 System.Collections.Generic.List`1[[xxx.Laundry.APIService.Models.Common.BaseModel, xxx.Laundry.APIService]] 
  6.     -> 0000000317e01ae0 xxx.Laundry.APIService.Models.Common.BaseModel[] 
  7.     -> 000000028010caf0 xxx.Laundry.APIService.Models.Common.BaseModel 
  8.     -> 00000003014cbbd0 System.Collections.Generic.List`1[[xxx.Laundry.Entities.V_InvoiceInfo, xxx.Laundry.Entities]] 
  9.     -> 00000003014f3580 xxx.Laundry.Entities.V_InvoiceInfo[] 
  10.     -> 00000003014cd7f0 xxx.Laundry.Entities.V_InvoiceInfo 
  11.     -> 000000038cc49bf0 System.Collections.Generic.List`1[[xxx.Laundry.Entities.V_InvoiceClothesInfo, xxx.Laundry.Entities]] 
  12.     -> 000000038cc49c18 xxx.Laundry.Entities.V_InvoiceClothesInfo[] 
  13.     -> 0000000180027800 xxx.Laundry.Entities.V_InvoiceClothesInfo 
  14.  
  15. Found 1 unique roots (run '!GCRoot -all' to see all roots). 

從輸出中可以看到,它貌似被一個 List 所持有,哈哈,總算找到了,接下來就簡單了,直接用 !objsize 看一看它的 size 有多大?

  1. 0:000> !objsize 00000004800238a0 
  2. sizeof(00000004800238a0) = -1972395312 (0x8a6fa2d0) bytes (System.Collections.Generic.List`1[[xxx.Laundry.APIService.Models.Common.BaseModel, xxx.Laundry.APIService]]) 

看到上面的 -1972395312 了嗎?我去,int 類型的 size 直接給爆掉了,果然是個大對象,就是你了。。。如果非要看大小也可以,寫一個腳本遍歷一下。

三:總結(jié)

知道是 List 做的孽后,仔細(xì)閱讀了源碼才知道,原來是給用戶第一次數(shù)據(jù)全量同步的時候,服務(wù)端為了加速將數(shù)據(jù)緩存在 List 這個靜態(tài)變量中,很遺憾的是并沒有在合適的時機(jī)進(jìn)行釋放,造成了高峰期內(nèi)存直線暴增,優(yōu)化方案很簡單,就是修改業(yè)務(wù)邏輯咯,增加釋放內(nèi)存的時機(jī)。

題外話

如果你遇到的是這種 Strong Handles 的靜態(tài)變量,也可以直接用可視化的 dotMemory 查看。

當(dāng)然你要保證你有足夠的內(nèi)存,畢竟也算是小10G的dump ??, 我的 16G 內(nèi)存一下子就被吃掉了。。。

善于用 String 駐留池機(jī)制來優(yōu)化,看看它的源碼定義吧。

  1. public sealed class String 
  2.    { 
  3.        [SecuritySafeCritical] 
  4.        public static string Intern(string str) 
  5.        { 
  6.            if (str == null
  7.            { 
  8.                throw new ArgumentNullException("str"); 
  9.            } 
  10.            return Thread.GetDomain().GetOrInternString(str); 
  11.        } 
  12.    } 

 

責(zé)任編輯:武曉燕 來源: 一線碼農(nóng)聊技術(shù)
相關(guān)推薦

2022-10-25 14:17:01

.NET代碼程序

2023-07-06 10:11:38

.NET模式dump

2024-09-14 10:28:56

.NET卡死程序

2023-07-31 22:29:20

CPU.NETAPI

2024-07-12 11:20:34

.NET崩潰視覺程序

2021-11-02 07:54:41

內(nèi)存.NET 系統(tǒng)

2021-04-21 07:38:41

CPU游戲站程序

2024-05-28 10:18:30

WPF程序數(shù)據(jù)

2023-04-06 10:52:18

2024-03-28 12:56:36

2021-10-09 10:24:08

NET爬蟲內(nèi)存

2023-04-26 12:48:58

.NET程序類型

2023-06-26 00:12:46

2024-12-27 13:31:18

.NETdump調(diào)試

2021-10-27 07:30:32

.NETCPU論壇

2023-05-15 11:15:50

.NET門診語句

2023-10-07 13:28:53

.NET軟件賬本

2024-05-31 12:56:06

.NET代碼方法

2023-06-29 17:55:00

.NET日志WinDbg

2024-07-01 13:00:24

.NET網(wǎng)絡(luò)邊緣計算
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 丝袜 亚洲 欧美 日韩 综合 | 色综合久 | 亚洲狠狠爱一区二区三区 | 久草在线高清 | 91免费电影 | 亚洲激精日韩激精欧美精品 | 18av在线播放 | 成人在线视频免费看 | 一区视频在线播放 | 自拍偷拍第一页 | 日韩视频一区二区在线 | 中文字幕视频在线看5 | 精品日韩 | 人人cao | 日韩欧美三区 | 韩日av片| 91网站在线播放 | 国产精品一区二区三区四区 | 日本在线免费观看 | 看片网站在线 | 久久久久久999 | 国产亚洲精品精品国产亚洲综合 | 国产精品久久久久久久久久免费 | 久久激情网 | 999精品视频 | 国产区在线观看 | 国产丝袜人妖cd露出 | 激情五月综合网 | 韩日在线视频 | 中文字幕国产视频 | 国产黄色小视频 | 色偷偷噜噜噜亚洲男人 | 精品久久久久久久 | 国产精品成人一区二区 | 亚洲人人 | 久久久久久一区 | 一区二区视屏 | 欧美日本韩国一区二区三区 | 国产一区二区日韩 | 久草中文在线 | 国产在线一区二区 |