PerfView专题 (第十三篇):洞察 .NET程序 的非托管句柄泄露

这篇具有很好参考价值的文章主要介绍了PerfView专题 (第十三篇):洞察 .NET程序 的非托管句柄泄露。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一:背景

1. 讲故事

前几天写了一篇 如何洞察 .NET程序 非托管句柄泄露 的文章,文中使用 WinDbg 的 !htrace 命令实现了句柄泄露的洞察,在文末我也说了,WinDbg 是以侵入式的方式解决了这个问题,在生产环境中大多数情况下是不能走附加进程的模式,所以这也是它最大的局限性。

那如何以非侵入的方式解决这个问题呢?这就是本篇讨论的重点,对,就是用 CLR 团队 鼎力推荐的 Perfview 来解决这个问题,哈哈,是我昨天看文档无意发现的 😁😁😁。

二:PerfView 分析

1. 测试案例

还是用那一篇文章的例子,让 C# 和 C++ 交互的时候产生句柄泄露, 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 <Windows.h>

using namespace std;

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

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

}

在 C# 中我用 Task 的形式调用 CSharpCreateEvent 函数来产生 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 分配监控

在 perfview 中可以开启内核级别的 OS Handle ETW事件 来进行分配和释放监控,用 +1-1 表示,为了让事件产生的更少,在 Focus process 中指定 Example_20_1_4.exe ,并且选中 Handle 复选框,截图如下:

PerfView专题 (第十三篇):洞察 .NET程序 的非托管句柄泄露

如果嫌面板太麻烦,可以使用 /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

接下来点击 Start Collection 开启收集,收集一会之后点击 Stop Collection,生成好 Zip 之后选择 Advanced -> Windows Handle Ref Count Stacks 选项,在弹出面板中选择我们的 Example_20_1_4 程序,删除 GroupPats 分组信息,处理后的截图如下:

PerfView专题 (第十三篇):洞察 .NET程序 的非托管句柄泄露

从上面的面板信息的 Handle Type Event 来看,当前有 5445 个 Event 事件没有被 Close,原来是 Event事件 的泄露哈,接下来在右键面板中选择 Goto -> Item in Callers 选项可以看到每一个 Event 的详细列表。

PerfView专题 (第十三篇):洞察 .NET程序 的非托管句柄泄露

最后就是抽选其中几个,观察到底是什么代码创建的 Event ? 截图如下:

PerfView专题 (第十三篇):洞察 .NET程序 的非托管句柄泄露

仔细观察面板信息,可以清楚的看到,原来是 Main 函数中有一个匿名方法,它在内部调用了 Example_20_1_5!CSharpCreateEvent 方法来创建句柄。

到这里就真相大白了。

三:总结

通过这个案例可以看到 PerfView 的最大好处就是无侵入性,WinDbg 和 Perfview 真的是一对好搭档,优势互补。文章来源地址https://www.toymoban.com/news/detail-572341.html

PerfView专题 (第十三篇):洞察 .NET程序 的非托管句柄泄露

到了这里,关于PerfView专题 (第十三篇):洞察 .NET程序 的非托管句柄泄露的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 深入理解JVM虚拟机第十三篇:详解JVM中的程序计数器

    😉😉 学习交流群: ✅✅1:这是孙哥suns给大家的福利! ✨✨2:我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料 🥭🥭3:QQ群:583783824   📚📚  工作微信:BigTreeJava 拉你进微信群,免费领取! 🍎🍎4:本文章内容出自上述:Spring应用课程!💞💞

    2024年02月08日
    浏览(54)
  • Java多线程&并发篇----第十三篇

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 Semaphore 是一种基于计数的信号量。它可以设定一个阈值,基于此,多个线程竞争获取许可信 号,做完自己的申请

    2024年01月20日
    浏览(36)
  • 二十三种设计模式第十三篇--享元模式

    享元模式,主要就是一种池化方案,主要用于创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于 结构型模式 ,它提供了减少对象数量从而改善应用所需的对象结构的方式。 享元模式,尝试重用现有的同类对象,如果未找到相同匹配的对象,那么就去创

    2024年02月12日
    浏览(43)
  • 【MySQL数据库 | 第十三篇】多表查询

    多表查询是指在一个SQL语句中使用多个表进行数据查询和操作。多表查询可以对数据表之间的关系进行查询,例如可以通过连接多个表来获取更完整的数据信息。关于单表查询我们也介绍过,已经整理成文章发布:【MySQL数据库 | 第九篇】DQL操作_我是一盘牛肉的博客-CSDN博客

    2024年02月08日
    浏览(55)
  • 【Pyhton入门系列】第十三篇:Python自动化测试和单元测试

    自动化测试是软件开发中不可或缺的一部分,它可以提高软件质量、减少人工测试工作量,并确保代码的稳定性。Python作为一种简洁而强大的编程语言,提供了丰富的测试框架和工具,使得自动化测试和单元测试变得更加容易。 自动化测试是指使用脚本或工具来执行测试任务

    2024年02月12日
    浏览(51)
  • 第十三篇【传奇开心果系列】Python的OpenCV库技术点案例示例:光流估计

    光流估计:OpenCV光流估计是一种用于分析图像序列中物体运动情况的技术。它通过计算相邻帧之间像素的位移来推断物体的运动轨迹和速度。用于分析图像序列中物体的运动情况。 光流估计算法基于一个假设:相邻帧之间的像素亮度保持不变。根据这个假设,算法比较两幅图

    2024年02月19日
    浏览(47)
  • PerfView 洞察C#托管堆内存 "黑洞现象"

    首先声明的是这个 黑洞 是我定义的术语,它是用来表示 内存吞噬 的一种现象,何为 内存吞噬 ,我们来看一张图。 从上面的 卦象图 来看,GCHeap 的 Allocated=852M 和 Committed=16.6G ,它们的差值就是 分配缓冲区=16G ,缓冲区的好处就是用空间换时间,弊端就是会实实在在的侵占内

    2024年02月16日
    浏览(50)
  • 【Git技巧】第十三篇 解决fatal: could not read Username for ‘https://‘: terminal prompts disabled

    目录 1、遇到问题 2、问题解决 fatal: could not read Username for \\\'https://gitlab.hdzk.cn\\\': terminal prompts disabled 这个错误通常发生在 Git 操作需要验证用户身份时,但终端提示被禁用的情况下。终端提示被禁用可能是因为您正在使用一个非交互式的终端会话,或者由于其他原因导致无法接收

    2024年02月08日
    浏览(46)
  • 【Love2d从青铜到王者】第十三篇:Love2d之游戏:射击敌人(Game: Shoot the enemy)

    让我们用目前所学的一切来创建一个简单的游戏。你可以随心所欲地阅读关于编程和制作游戏的书籍,但要真正学会,你必须亲自动手。 一个游戏本质上是一堆你必须解决的问题。当你让一个有经验的程序员做PONG的时候,他不会去查a如何制作乒乓球。他们可以将PONG分成不同

    2024年01月19日
    浏览(36)
  • 如何洞察 .NET程序 非托管句柄泄露

    很多朋友可能会有疑问,C# 是一门托管语言,怎么可能会有非托管句柄泄露呢? 其实一旦 C# 程序与 C++ 语言交互之后,往往就会被后者拖入非托管泥潭,让我们这些调试者被迫探究 非托管领域问题 。 为了方便讲述,我们上一个 Event 泄露的案例,使用 C# 调用 C++ ,然后让

    2024年02月12日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包