av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

PerfView洞察 .NET程序 非托管句柄泄露

一:背景

1. 講故事

前幾天寫了一篇 如何洞察 .NET程序 非托管句柄泄露 的文章,文中使用 WinDbg 的 !htrace 命令實(shí)現(xiàn)了句柄泄露的洞察,在文末我也說了,WinDbg 是以侵入式的方式解決了這個(gè)問題,在生產(chǎn)環(huán)境中大多數(shù)情況下是不能走附加進(jìn)程的模式,所以這也是它最大的局限性。

那如何以非侵入的方式解決這個(gè)問題呢?這就是本篇討論的重點(diǎn),對(duì),就是用 CLR 團(tuán)隊(duì) 鼎力推薦的 Perfview 來解決這個(gè)問題,哈哈,是我昨天看文檔無意發(fā)現(xiàn)的 。

二:PerfView 分析

1. 測(cè)試案例

還是用那一篇文章的例子,讓 C# 和 C++ 交互的時(shí)候產(chǎn)生句柄泄露, C++ 代碼如下:

// Example_20_1_5.cpp : This file contains the 'main' function. Program execution begins and ends there.
//

extern "C"
{
 _declspec(dllexport) void CSharpCreateEvent();
}

#include "iostream"
#include 

using namespace std;

void CSharpCreateEvent()
{
 HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

 printf("\nEvent句柄值: %#08x ", hEvent);

}

在 C# 中我用 Task 的形式調(diào)用 CSharpCreateEvent 函數(shù)來產(chǎn)生 Event 句柄泄露,參考代碼如下:

internal class Program
    {

        [DllImport("Example_20_1_5", CallingConvention = CallingConvention.Cdecl)]
        extern static void CSharpCreateEvent();

        static void Main(string[] args)
        {
            try
            {
                while (true)
                {
                    Task.Run(() =>
                    {
                        CSharpCreateEvent();
                    });

                    Thread.Sleep(10);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            Console.ReadLine();
        }
    }

2. Handle 分配監(jiān)控

在 perfview 中可以開啟內(nèi)核級(jí)別的 OS Handle ETW事件 來進(jìn)行分配和釋放監(jiān)控,用 +1 和 -1 表示,為了讓事件產(chǎn)生的更少,在 Focus process 中指定 Example_20_1_4.exe ,并且選中 Handle 復(fù)選框,截圖如下:

圖片

如果嫌面板太麻煩,可以使用 /KernelEvents:Handle,Default 命令即可,完整的 Command 命令如下:

PerfView.exe  "/DataFile:PerfViewData.etl" /BufferSizeMB:256 /StackCompression /CircularMB:500 /KernelEvents:Handle,Default /NoGui /FocusProcess:"Example_20_1_4.exe" /NoNGenRundown collect

接下來點(diǎn)擊 Start Collection 開啟收集,收集一會(huì)之后點(diǎn)擊 Stop Collection,生成好 Zip 之后選擇 Advanced -> Windows Handle Ref Count Stacks 選項(xiàng),在彈出面板中選擇我們的 Example_20_1_4 程序,刪除 GroupPats 分組信息,處理后的截圖如下:

圖片

從上面的面板信息的 Handle Type Event 來看,當(dāng)前有 5445 個(gè) Event 事件沒有被 Close,原來是 Event事件 的泄露哈,接下來在右鍵面板中選擇 Goto -> Item in Callers 選項(xiàng)可以看到每一個(gè) Event 的詳細(xì)列表。

圖片

最后就是抽選其中幾個(gè),觀察到底是什么代碼創(chuàng)建的 Event ?截圖如下:

圖片

仔細(xì)觀察面板信息,可以清楚的看到,原來是 Main 函數(shù)中有一個(gè)匿名方法,它在內(nèi)部調(diào)用了 Example_20_1_5!CSharpCreateEvent 方法來創(chuàng)建句柄。

到這里就真相大白了。

三:總結(jié)

通過這個(gè)案例可以看到 PerfView 的最大好處就是無侵入性,WinDbg 和 Perfview 真的是一對(duì)好搭檔,優(yōu)勢(shì)互補(bǔ)。


網(wǎng)頁(yè)標(biāo)題:PerfView洞察 .NET程序 非托管句柄泄露
文章地址:http://uogjgqi.cn/article/cdischp.html
掃二維碼與項(xiàng)目經(jīng)理溝通

我們?cè)谖⑿派?4小時(shí)期待你的聲音

解答本文疑問/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流