一:背景
上一篇我們聊到了如何去找 熱點函式,這一篇我們來看下當你的程式出現了 非托管記憶體泄漏 時如何去尋找可疑的代碼源頭,其實思路很簡單,就是在 HeapAlloc 或者 VirtualAlloc 時做 Hook 攔截,記錄它的呼叫堆疊以及分配的記憶體量, PerfView 會將這個 分配量 做成一個 權重,最后可以根據 權重 高低來找到有問題的呼叫堆疊,
二:案例演示
為了方便講述,我們演示一個 Windows 的 Nt堆 記憶體泄漏,讓 C# 呼叫 C++ 代碼時故意泄漏記憶體,代碼如下:
#include <iostream>
extern "C"
{
_declspec(dllexport) int calc_size(int size);
}
int calc_size(int size) {
int* buffer = new int[size];
return 2 * size;
}
然后在 C# 中匯入這個 C++ 的 dll,
internal class Program
{
[DllImport("ConsoleApplication2.dll", CallingConvention = CallingConvention.Cdecl)]
extern static int calc_size(int size);
static void Main(string[] args)
{
for (int i = 0; i < int.MaxValue; i++)
{
var size = calc_size(1000);
Console.WriteLine($"i={i}");
}
}
}
接下來把程式跑起來,再打開 Perfview,在 OS Heap Process 輸入框填入行程號19404,監控 15s然后 Start Collection即可,這么做的目的時攔截 HeapAlloc 和 HeapFree 方法,截圖如下:
稍等 15s 之后,打開 Memory / Net OS Heap Alloc Stacks 選項卡,
接下來切到 CallTree 選項卡,清除掉 GroupPats 中的條件,觀察各自的呼叫堆疊,截圖如下:
從圖中的 inc % 列可以看到,calc_size 方法的 分配權重量 占 總分配量的 99.9% ,這就說明此方法有很大的嫌疑,最后就是查看原始碼了哦,
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/501658.html
標籤:C#
