共用方式為


使用核心偵錯工具尋找 Kernel-Mode 記憶體流失

核心偵錯工具會決定核心模式記憶體流失的精確位置。

啟用集區標記

您必須先使用 GFlags 來啟用集區標記。 GFlags 包含在 Windows 的偵錯工具中。 啟動 GFlags,選擇 [系統登錄 ] 索引標籤,核取 [ 啟用集區標記 ] 方塊,然後選取 [ 套用]。 您必須重新開機 Windows,此設定才會生效。

在 Windows Server 2003 和更新版本的 Windows 上,一律會啟用集區標記。

判斷流失的集區標籤

若要判斷哪一個集區標籤與流失相關聯,通常最簡單的方式是針對此步驟使用 PoolMon 工具。 如需詳細資訊,請參閱 使用 PoolMon 尋找 Kernel-Mode 記憶體流失

或者,您可以使用核心偵錯工具來尋找與大型集區配置相關聯的標籤。 若要這樣做,請遵循此程式:

  1. 使用 .reload (Reload Module) 命令重載所有模組。

  2. 使用 !poolused 擴充功能。 包含旗標 「4」,依分頁記憶體使用量排序輸出:

    kd> !poolused 4 
    Sorting by Paged Pool Consumed
    
    Pool Used:
                NonPaged            Paged     
    Tag    Allocs     Used    Allocs     Used 
    Abc         0        0     36405 33930272 
    Tron        0        0       552  7863232 
    IoN7        0        0     10939   998432 
    Gla5        1      128      2222   924352 
    Ggb         0        0        22   828384 
    
  3. 判斷哪個集區標籤與記憶體的最大使用量相關聯。 在此範例中,使用 「Abc」 標籤的驅動程式正在使用最多記憶體,幾乎是 34 MB。 因此,記憶體流失很可能在此驅動程式中。

尋找流失

判斷與流失相關聯的集區標籤之後,請遵循此程式找出流失本身:

  1. 使用 ed (Enter Values) 命令來修改全域系統變數 PoolHitTag的值。 這個全域變數會在使用符合其值的集區標籤時中斷偵錯工具。

  2. PoolHitTag 設定為您懷疑為記憶體流失來源的標籤。 應該指定模組名稱 「nt」 來加快符號解析速度。 標籤值必須以小到尾格式輸入, (也就是回溯) 。 因為集區標籤一律是四個字元,所以這個標記實際上是 A-b-c-space,而不只是 A-b-c。 因此,請使用下列命令:

    kd> ed nt!poolhittag ' cbA' 
    
  3. 若要確認 PoolHitTag目前的值,請使用 db (Display Memory) 命令:

    kd> db nt!poolhittag L4 
    820f2ba4  41 62 63 20           Abc  
    
  4. 每次組態集區或釋放標籤 Abc時,偵錯工具都會中斷。 每次偵錯工具中斷上述其中一個配置或可用作業時,請使用 kb (顯示堆疊回溯) 偵錯工具命令來檢視堆疊追蹤。

使用此程式,您可以判斷位於記憶體中的哪些程式碼正在過度配置標籤 Abc的集區。

若要清除中斷點,請將 PoolHitTag 設定為零:

kd> ed nt!poolhittag 0 

如果有數個不同的位置會配置此標記的記憶體,而且這些位置位於您已撰寫的應用程式或驅動程式中,您可以改變原始程式碼,以針對每個配置使用唯一標記。

如果您無法重新編譯程式,但想要判斷程式碼中數個可能位置中的哪一個位置造成流失,您可以在每個位置取消編譯器代碼,並使用偵錯工具來編輯存放在記憶體中的此程式碼,讓每個實例使用不同的 (,而且先前未使用的) 集區標記。 然後讓系統執行數分鐘以上。 經過一段時間之後,請再次使用偵錯工具中斷,並使用 !poolfind 延伸模組來尋找與每個新標記相關聯的所有集區配置。