1. 程式人生 > >Windbg程式除錯系列2-記憶體洩露問題

Windbg程式除錯系列2-記憶體洩露問題

上篇文章給大家解釋了Windbg的基本命令和說明,這一篇給大家介紹記憶體洩露場景的問題分析。

文章大綱:

  1. 描述問題背景和現象
  2. 確定問題是否是記憶體洩露
  3. 梳理問題分析思路
  4. 動手分析解決
  5. 總結

1. 先說問題背景:生產環境IIS站點,執行一段時間後,w3wp程序記憶體會漲到2G,同時記憶體不釋放。

2. 問題確認

開啟效能計數器,我們重點看一段時間內,IIS站點w3wp程序相關的效能計數器的變化:

效能計數器中:有三個非常重要:

.NET CLR Memory/Gen 2 heap size.NET CLR Memory/Gen 1 heap size.NET CLR Memory/Gen 0 heap size託管堆上的物件有三代:第 0 代: 這是最年輕的代,其中包含短生存期物件。 短生存期物件的一個示例是臨時變數。 垃圾回收最常發生在此代中。新分配的物件構成新一代的物件並且為隱式的第 0 代回收,除非它們是大物件,在這種情況下,它們將進入第 2 代回收中的大物件堆。大多數物件通過第 0 代中的垃圾回收進行回收,不會保留到下一代。第 1 代: 這一代包含短生存期物件並用作短生存期物件和長生存期物件之間的緩衝區。第 2 代: 這一代包含長生存期物件。 長生存期物件的一個示例是伺服器應用程式中的一個包含在程序期間處於活動狀態的靜態資料的物件。當條件得到滿足時,垃圾回收將在特定代上發生。 回收某個代意味著回收此代中的物件及其所有更年輕的代。 第 2 代垃圾回收也稱為完整垃圾回收FullGC,因為它回收所有代上的所有物件(即,託管堆中的所有物件)。倖存和提升:垃圾回收中未回收的物件也稱為倖存者,並會被提升到下一代。 在第 0 代垃圾回收中倖存的物件將被提升到第 1 代;在第 1 代垃圾回收中倖存的物件將被提升到第 2 代;而在第 2 代垃圾回收中倖存的物件將仍為第 2 代。通過代提升,看物件的存活時間!

Process/Private BytesProcess/Virtual Bytes.NET CLR Memory/# Bytes in all Heaps : CLR記憶體託管堆的大小.NET CLR Memory/Large Object Heap Size: 大物件堆包含其大小為 85,000 個位元組和更多位元組的物件。

託管堆的記憶體大小增加的趨勢和大物件堆增加的趨勢重疊,可以初步推斷,記憶體的增加和大物件有關係!

3. 梳理問題分析思路

連續、間隔抓兩個或者三個Dump,每次抓Dump間隔半個小時,或者一個小時,主要看記憶體的增量。

對比的看每個Dump中:

  • 多核CPU情況下,分析每個GC託管堆的大小 !eeheap –gc
  • 查詢記憶體中各類物件的總個數和總記憶體佔用 !dumpheap –stat
  • 查詢記憶體中大物件的個數和物件大小 !dumpheap –stat -mt -min 5000 -max 100000
  • 如果某一類或者幾類物件的記憶體總佔用很多,分析此類物件 !dumpheap –mt ***
  • 多次取樣檢視步驟4中物件的gcroot !gcroot addr
  • 打斷gcroot中任何一個鏈條,釋放物件引用

4. 動手分析

  • 多核CPU情況下,分析每個GC託管堆的大小 !eeheap –gc

      

  • 查詢記憶體中各類物件的總個數和總記憶體佔用 !dumpheap –stat

      

  • 查詢記憶體中大物件的個數和物件大小 !dumpheap –stat -mt -min 5000 -max 100000

      

  • 如果某一類或者幾類物件的記憶體總佔用很多,分析此類物件 !dumpheap –mt *** -stat

      

      大物件字串分析,Session會話資料!同時Session會話中包含了許可權資料!

  • 多次取樣檢視步驟4中物件的gcroot !gcroot addr

      

  • 打斷gcroot中任何一個鏈條,釋放物件引用

5. 總結

總結一下,記憶體洩露問題分析,有固定的方法和指令,過程需要大家深入理解,同時熟悉程式碼非常重要,因為需要找出gcroot,分析出記憶體洩露的原因,再進行修改解決。

大的套路:

  • 描述問題背景和現象
  • 確定問題是否是記憶體洩露
  • 梳理問題分析思路
  • 動手分析解決
  • 總結

詳細的分析步驟:

  • 多核CPU情況下,分析每個GC託管堆的大小 !eeheap –gc
  • 查詢記憶體中各類物件的總個數和總記憶體佔用 !dumpheap –stat
  • 查詢記憶體中大物件的個數和物件大小 !dumpheap –stat -mt -min 5000 -max 100000
  • 如果某一類或者幾類物件的記憶體總佔用很多,分析此類物件 !dumpheap –mt ***
  • 多次取樣檢視步驟4中物件的gcroot !gcroot addr
  • 打斷gcroot中任何一個鏈條,釋放物件引用

歡迎大家補充。

周國慶

2018/10/30