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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

dump文件解析之探索.Net的内存

發布時間:2023/12/4 asp.net 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 dump文件解析之探索.Net的内存 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言:

對于需要長時間運行的.net程序,有時需要我們查看內存的使用有沒有內存泄露問題。

我們可以從dump文件中找到答案。

?

Dump的看點

用dump文件來分析內存,到底我們需要關心哪些點呢?

  • 內存的使用情況 HeapSize/object的數量 也就是托管堆使用大小以及托管堆內有多少數量的對象

  •     1.1 ?查看有沒有存在有占用大量內存的對象 <比如有某類下面的一個集合>

         ?1.2? 0 1 2各代的size<查看各代的內存是否有異常>

    ?

    ?????? 2.調查是否有內存泄露(重點)

        2.1 ?查看object的根(Root) 看看GC回收不了的有哪些

        2.2<我們知道一個對象Root下沒有引用就會標為可Gc對象,如果一個對象你希望被gc回收但寫代碼不注意又在別的地方保存了引用就會出現內存泄露>

      3. ?終結器是否被阻塞時,當終結器線程被阻塞時,Finalize會等待累積(末尾有例子)

    ?

    用什么工具

    • Visual Studio

    • DebugDiag

    • WinDbg

    • dotMemory(JetBrains旗下的 我還沒研究過)

    以上三款是微軟給我們提供的工具,注意VS得要是Enterprise才可以哦。其他的兩款都是免費的。

    ?

    我們先寫一個sample程序

    ?

    然后運行

    ?

    ?

    ?

    ?

    一.用Visual Studio

    打開dump文件

    ?

    ?

    點擊按鈕 【調試托管內存】

    ?

    ?

    可以很清楚的看到有多少對象,每個對象共使用了多少內存

    在這個一覽下方有2個視圖 分別是

    1.根的路徑

    ?

    ?

    比如我們選擇 ConsoleApp2.B 這個對象

    ?

    從這個圖可以看出來 B 這個對應 的 Paths To Root的追溯情況 (也就是構建最終要GC的Root)

    ?Program._values(static變量) -> List<A> -> B

    我們可以看到values就是B的Root 只要values不存在那B就會納入gc的回收對象中

    因為我們是在Hold住了這個程序的main方法所以在這個時候B 對象還不能被gc回收

    2.引用的類型

    ?

    ?

    如何我們選擇List<ConsoleApp3.A>

    那么就會展示List<ConsoleApp3.A>的引用關系如下圖所示:

    ?

    ?

    從這個圖我們可以看出來 List<A> 持有 A[] ,A[]持有 A,A持有B

    以上根據這2個視圖我們可以利用Vs來看出:

    ?咦?這個對象占用內存怎么這么大 有點可疑

    這個對象不是應該被gc嗎,怎么沒有被gc呢?研究下他的gc root看看

    ?

    二.DebugDiag

    下載地址?https://www.microsoft.com/en-us/download/details.aspx?id=49924

    ?

    ?

    ?

    點擊 【Add Data Files】 添加Dump文件后 點擊 【Start Analysis】 執行

    執行成功后會自動用 IE 打開。

    ?

    ?

    其實和 VS比起來差不多,直接生成一個報告也是比較方便的!

    ?

    三.WinDbg

    雖然使用上比較麻煩但是winDbg可以幫助我們分析的更加詳細

    可以從微軟官方下載,為了方便百度云下載地址:

    鏈接: https://pan.baidu.com/s/1eblPm4nuN0F-DkY_FzqUvA 提取碼: zmtd

    注意要設置下Symbol Path

    ?

    ?

    重新設置符號文件路徑如下;

    SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols

    ?

    ?

    意思是如果在本地找不到則從微軟網站下載

    ?

    Ok設置完成后用WinDbg載入dump文件

    ?

    ?

    如下圖所示:

    ?

    ?

    打開成功后我們還不能開始分析必須

    要先執行加載SOS和CLR(對于.Net?Runtime?4.0)

    ?【 !loadby sos clr】 命令

    ?

    接下來我們用WinDbg來調查內存使用情況:

    一般我們定位內存泄露問題,我總結的原則是要查到什么對象占用了大量內存,為什么它沒有被GC。我們分以下幾個步驟

    1.統計內存中的對象&查找有異樣的對象

    使用命令 【!DumpHeap -stat】

    可以把堆中的對象類型和size給打印出來

    ?

    我們可以看出來 A 和 B 是可疑對象

    2.根據類型查找存活對象一覽

    接下來我們根據查找出A的一覽

    使用命令【!DumpHeap -live -mt <MT addr>】

    ?

    結果如下:

    ?

    可以看出內存中A類型的對象有100000個

    3.探索從某個對象找出GC ROOT一覽

    使用命令【!GCRoot 】

    ?

    ?

    ?

    其實可以看出來和Visual Studio的【根的路徑】要點差不多吧。

    ?

    WinDbg的其他常用命令

    1. !DumpHeap -stat 查找托管堆按類型分組統計個數以及占用的總內存大小

    ?

    2.!HeapStat 查找當前堆中各代的內存使用量 以及剩余使用量

    ?

    3.!DumpHeap -live -mt <MT addr> 從MethodTable中查找存活的對象一覽

    ?

    4.!DumpHeap -dead -mt <MT addr> 從MethodTable中查找要在下次FullGC要回收的一覽

    ?

    5.!DumpMT -md <MT addr> 查看類型信息 (加了-md參數會把這個類型下的方法(MethodDescriptor)都打印出來)

    ?

    6.!DumpClass <EEClass addr> 指定EEClass的地址

    ?

    7.!Threads 查看Finalizer有沒有導致死鎖的例子

    ?

    ?? 如上圖所示, 用!Threads可以找出 Finalizer的線程為13.。接下來用命令 ~13k 查看線程執行棧,

    ?

    ?

    上圖是正常的情況沒有問題。執行WaitForFinalizerEvent等下一次執行信號

    參考?https://github.com/dotnet/coreclr/blob/ca013149100a9ccc69a5df5b80f29fed2b1b0ce8/src/vm/finalizerthread.cpp#L571

    ?

    ?下圖是死鎖情況

    ?

    ?

    可以看到有 CallFinalizer 和 FinalizeAllObjects 表示正在處理什么東西

    在用命令【~[ID]e!clrstack】查看CLR的執行棧情況

    ?

    ?

    可以看出是在Finalize里面用了 Thread.Sleep導致的

    ?

    ?

    使用SOSEX更方便的使用WinDbg

    sosez是sos的擴展工具集(就是一個dll文件),下載官網地址:http://www.stevestechspot.com/

    下載完后要加載到 WinDbg里面去 使用命令 .load 進行加載

    ?

    它集成了很多簡單使用的指令

    例如: !mdt 可以根據 類型 進行篩選

    ?

    ?

    藍色處可以直接點擊查看,功能很強大

    ?

    ?

    ?

    總結

    .Net程序運行期間會遇到很多奇怪的問題,通過分許Dump文件分析內存情況是一個很好的切入口。

    不管用什么工具,按照以下幾個步驟:

    • 統計內存中的對象

    • 查找有異樣的對象 比如這個對象數量多的有點反常,本來期待會被GC回收但是卻沒有

    • ?根據類型查找存活對象一覽

    • 探索從某個對象找出GC ROOT一覽

    一定會讓你有所發現。

    相關文章:

    • dump解析入門-用VS解析dump文件進行排障

    • 生產環境診斷利器WinDbg幫你快速分析異常情況Dump文件

    • Windbg Extension NetExt 使用指南 ---- NetExt 介紹

    • Windbg Extension NetExt 使用指南 ?---- NetExt 的基本命令介紹

    • Windbg Extension NetExt 使用指南 ?---- 挖掘你想要的數據 Managed Heap

    原文地址:?https://www.cnblogs.com/yudongdong/p/9701727.html


    .NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com

    總結

    以上是生活随笔為你收集整理的dump文件解析之探索.Net的内存的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。