WinDbg調試高內存的.Net進程Dump


WinDbg的學習路徑,艱難曲折,多次研究進展不多,今日有所進展,記錄下來。

微軟官方幫助文檔非常全面:https://msdn.microsoft.com/zh-cn/library/windows/hardware/ff551063(v=vs.85).aspx

問題發現在服務器上,服務器為WinServer2012 R2 x64。其中一個Windows服務,內存高達7G。但此服務,無什么操作,僅僅定時獲取數據,更新數據。使用的EntityFramework。用任務管理器,抓包下來,查看。Dump包有7GB之大。

1、准備環境,加載sos.dll===========================

開始調試,首先WinDbg,分為x64和x86版本。由於Dump運行環境,為64位,故WinDbg也應64位,這就要主機調試環境也應64位。我主機環境為win8.1x64。

運行WinDbg,一定要管理員權限。

然后,確認是否已加載sos.dll。使用.chain命令,查看。若未加載,則加載64位的sos.dll。因為Dump是x64位的,故加載x32位不成,會提示

"The call to LoadLibrary(C:\Windows\Microsoft.NET\Framework\v4.0.30319\sos.dll) failed, Win32 error 0n193

"%1 不是有效的 Win32 應用程序。""

sos.dll微軟官方幫助文檔,https://msdn.microsoft.com/en-us/library/bb190764(v=vs.110).aspx

2、調試===================================

1)、.cls清屏。
2)、!eeheap -gc 查看托管堆,發現2代堆非常大,近2.5G。故確定問題在此。

每個Segment最大255M,begin為起始地址,allocated為結束地址,結束地址減去起始地址等於size,括號里為10進制大小。LOB並不大。

  

3)、由於dump很大,全分析很慢,故只取一個二代堆的Segment分析。!DumpHeap 000000008f591000  000000009f58ffe0 

4)、分析幾分鍾后,stat統計節顯示String類型最大。故再次分析String類型。!DumpHeap -type String  000000008f591000  000000009f58ffe0 

5)、發現String類型,有很多4KB字符串,不知什么。進一步分析大字符串,!DumpHeap -type String -min 1000  000000008f591000  000000009f58ffe0 

6)、!do 查看對象,發現String是錯誤信息。聯系之前,此系統確實一直出現報錯行為,但不影響使用也就沒管。

7)、!gcroot -all 查看引用 ,此操作也比較慢。發現String是一個對象屬性,而對象是EF5的Context表記錄。

8)、重復6)、7)步驟,發現都是如此。那么這個Context一直有效,其中內容也就一直被引用。

8)、這時,用IL查看代碼,發現確實有個靜態的EF的ObjectContext被引用,此對象生命期與進程一致。由於長期運行,加入數據,ObjectContext會一直增加。

關於這個問題,我找了下EF相關文檔,似乎沒有清理DBContext的命令。

其實,這種操作非常常見,為此,我單獨做了測試程序,證明了以上結論。 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication12
{
    class Program
    {


        static IT_MonitorEntities DB = new IT_MonitorEntities();

        static void Main(string[] args)
        {
            while (true)
            {
                Console.WriteLine("是否調用Add Y/N");
                ConsoleKeyInfo k = Console.ReadKey();
                Console.WriteLine("");
                if (k.Key == ConsoleKey.Y)
                {
                    Console.WriteLine("Add ");
                    Add();
                }
            }

        }

        static void Add()
        {
            for (int i = 0; i < 1000; i++)
            {
                DB.JobNotifies.Add(new JobNotify()
                {
                    Remark = i.ToString() + " " + invarStr
                });
                DB.SaveChanges();
            }
        }

        static string invarStr = @"你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒
你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒你巍峨阿斯頓發地方阿斯頓發啊上帝發誓地方撒";

    }
}

  

3、幫助信息================

1)、WinDbg可使用!help cmd.獲取幫助,比如!help dumpheap

2)、可用搜索內存s -u 0x017a1000 0x017c8c78 "朝生暮死"

或搜索內存到底 .foreach (addr { s -[1]u 0x017a1000 0x017c8c78 "朝生暮死"}){du ${addr}}

3)、


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM