【ZeloEngine】C++内存泄漏检测
需求
- 定位泄漏内存的分配代码
- 屏蔽模块,比如屏蔽第三方库,以及用于二分定位
内存泄漏的主要问题是会导致不应该的内存占用高
反过来说,内存占用高到影响运行,才需要来检测内存泄漏
平时开发,吃不准内存生命周期时,也可以用工具来验证一下
SDL_Init里有一个new int,每次都会报它泄漏,因为他没有回收
这种泄漏就无伤大雅,没必要改,应该加入ignore
工具
- windows,vld,crtdbg(vld更好)
- linux,valgrind(没用过,clion已经集成)
工具有false-positive的问题,需要调教
如何写不会泄漏的代码
- 厘清内存生命周期
- 仅在小范围内使用new和delete
- 大部分情况使用unique_ptr替代裸指针
- 复杂情况使用GC
MISC * 基类的析构函数必须是虚函数
案例分析
【LuaAI引擎魔改】-03-内存泄露 - 左亦的文章 - 知乎
CrtDbg
虽然不用了,但是归档一下笔记
跟踪new和delete,包括封装指针为句柄,添加全局管理指针泄漏的数据结构
在程序启动和退出时,做内存快照进行diff,对比出没有回收的内存,输出报告
- Windows的CRT库在debug版本创建调试堆
- 堆内存=0xCDCDCDCD
- 栈内存=0xCCCCCCCC
- 被释放的堆内存重新分配前=0xFEEEEEEE
§ 有时,将被释放的内存=0xDDDDDDDD - ????
- 总之,调试堆通过这种方式来标识内存状态
- 测试一下,使用强制在0处分配内存等方式,查看VS的内存窗口
- 函数
- _CrtSetDbgFlag:设置调试堆的参数和行为
- _CrtCheckMemory:检查
- _CrtDumpMemoryLeak:输出报告
- _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF
- _CRTDBG_ALLOC_MEM_DF
§ free的内存不要放回freelist,而是专门保存在一个特殊的list,一遍跟踪内存损坏 - _CRTDBG_LEAK_CHECK_DF
§ 每次malloc和free都进行内存检查(_CrtCheckMemory)
|