厚积薄发
海纳百川,有容乃大
posts - 79,comments - 170,views - 17万
Window上我们常见的资源泄露包括内存和对象句柄泄露, 下面讨论下对各类泄露的检测方法。
关于内存泄漏,我以前写过2篇文章: C++中基于Crt的内存泄漏检测, 基于WinDbg的内存泄漏分析
用上面提到的方法检测泄露很多时候太麻烦,所以有时候我们会考虑用工具 VLD:

Visual Leak Detector源于Code ProjectVisual Leak Detector - Enhanced Memory Leak Detection for Visual C++安装包可以到 这里 下载。

使用很简单,基本上安装完了就之可以直接用, 具体可以参考 这篇


关于对象句柄泄露, 主要分GDI对象,Kernel对象,User对象:

GDI对象只在本进程有效,主要是指Brush, Pen,DC等, 具体可以参考 这里

User对象只在同一Session内有效,同一user对象在不同进程内值都相等,可以跨进程使用, 主要是指Menu, window, cursor, hook等,具体可以参考 这里

Kernel对象可以跨进程使用, 但是因为每个进程都有自己的内核对象表,所以同一对象的句柄值在不同进程里会不相等(尽管最终指向同一个内核对象),主要是指各类HANDLE,具体可以参考 这里


对于对象句柄泄露,免费来说没有太好的工具可以直接使用, 很多时候我们可以直接通过任务管理器来观察各类对象的个数, 如果有持续增长, 则说明有泄露存在。很多时候GDI泄露是大头,我们要判断哪类GDI对象正在泄露,可以考虑使用工具GDIView。(对于对象句柄泄露,谁有好的工具,可以提示下。)


对于内核对象泄露,我们可以考虑使用WinDbg的 !htrace 命令, 使用很简单:通过 !htrace -enable 命令打开栈回溯, 然后通过 !htrace -snapshot 命令保存一个当前所有句柄的快照, 最后再通过 -htrace -diff 命令获取所有前面保存快照后打开但没有关闭的句柄对象。


如果公司有钱,可以考虑购买Boudcheck, 这个工具非常强大,可以帮我们快速的检测出各类内存和对象泄露,包括API的参数错误等。思考Boundcheck的实现原理,实际上并不复杂,主要就是API Hook, 大概过程如下:

(1) 将注入对方进程

(2) 通过API Hook替代系统资源分配和释放相关的API, 并且记录调用栈

(3)最后检测没有释放的资源, 生成报表


这里有篇文章告诉你如何开发类似的工具:LeakMon - Track Handle leak, GDI Leak and Memory Leak in your Applications

当然尽管原理很简单,但是因为Windows的API种类繁多,并且在新版本中会常有增加, 要开发一个完整的工具也不是一件容易的事情。

posted on   Richard Wei  阅读(1423)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示