[toc]
前言
本文为项目中服务程序的内存泄漏,挑了其中一部分比较常见的内存泄漏进行分析和修改。
关于内存泄漏和分析的文章可查看博客相关文章,有 UMDH
和 vld
两种方式,可根据个人需求展开分析。
泄漏分类
# malloc
内存泄漏
下述日志为一次 malloc
未正确释放导致的内存泄漏。这种问题比较常见,不用多说。
1 2 3
| ntdll.dll!RtlAllocateHeap() ***\heap\malloc_base.cpp (34): XXX.dll!_malloc_base() + 0xF bytes XXX.dll!_event_debugx() + 0x1A7 bytes
|
解决方案:
根据提示的位置找到并释放该内存。
1 2 3
| char *ch = (char*)malloc(sizeof(8)); free ch; ch = NULL;
|
另外,也可以使用智能指针管理该指针:
1 2
| char *ch = (char*)malloc(sizeof(8)); shared_ptr<char> spCh(ch);
|
# new
内存泄漏
关于 new
的内存泄漏分析写了一段代码用来展示一下:
注:代码 Section2 部分为一个崩溃代码,堆内存申请后使用时一处,而在堆内存申请和释放时以及程序结束时释放堆内存时,都 存在堆溢出检查 ,检查点会抛出异常,导致程序奔溃。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
int* test_heap_alloc() { int* pTable = new int(256); for (int i = 0; i < 256; i++) pTable[i] = i; return pTable; }
int main () { test_heap_alloc(); char* p = new char(0); return 0; }
|
以下为 vld 生成的泄漏日志:
1 2 3 4 5 6 7 8 9 10 11 12
| WARNING: Visual Leak Detector detected memory leaks! ---------- Block 1 at 0x010AAC68: 4 bytes ---------- Leak Hash: 0x03729B3D, Count: 1, Total 4 bytes Call Stack (TID 33760): ucrtbase.dll!malloc() d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\heap\new_scalar.cpp (35): vldforptr.exe!operator new() + 0x8 bytes d:\code_source\c++\vs2019\vldforptr\vldforptr.cpp (45): vldforptr.exe!main() + 0x7 bytes KERNEL32.DLL!BaseThreadInitThunk() + 0x19 bytes ntdll.dll!RtlGetAppContainerNamedObjectPath() + 0x11E bytes ntdll.dll!RtlGetAppContainerNamedObjectPath() + 0xEE bytes Data: 00 00 00 00 ........ ........
|
解决方案:
调用 delete
释放 new
出来的内存。
-
问题:不确定变量什么时候使用完的,如何释放?
1 2 3
| char *ch = new char[256]; std::shared_ptr<char> spCh(ch);
|
# strdup
内存泄漏
strdup
函数说明:
功能:将字符串拷贝到新建的位置处
返回值 :返回一个指向新字符串的指针,该字符串是字符串s的副本,如果分配空间失败,则返回NULL值。新字符串的内存由strdup函数原型内部的malloc()获得,需用free()释放。
1 2 3
| ntdll.dll!RtlAllocateHeap() minkernel\crts\ucrt\src\appcrt\heap\malloc_base.cpp (34): XXX.dll!_malloc_base() + 0xF bytes XXX.dll!BUF_strndup() + 0x8A bytes
|
把返回内存地址的释放权交给了别的变量,这就很容易忘记释放,所以 strdup
这个函数也很容易造成内存泄漏。
整理
# _malloc_base
_malloc_base
就是编译器编译之后的 malloc
。
查看vld的log可以看到,堆栈显示的 _malloc_base
所在的文件夹为 minkernel\crts\ucrt\src\appcrt\heap\malloc_base.cpp
,这个文件就是 malloc
声明和定义的文件。
1 2 3 4 5 6 7
| 领导您好! 以下内容为本次绩效期间我的工作概述以及自我评价。
本次绩效期间,我的主要工作内容集中在零信任国信版本和天擎零信任插件部分,同时也负责了部分工行、标板的需求开发(SPA、异常告警、命令行登录等)。零信任国信版本共计发布版本两次,均在发布版本之前完成了需求的开发和bug的修复,涉及的需求十多项,需求提测均通过,在完成需求的同时,整理编写了相应的技术开发文档十多篇,同时也补充了零信任客户端部分配置文件的说明文档。开发同时,针对国信零信任版本的升级故障问题(升级失败,升级检测问题),优化了该部分的逻辑,对整个客户端的无逻辑代码和日志部分进行了优化,以便于后续快速定位和分析问题,国信发布版本期间,为保证出包顺利,解决临时出现的问题,与团队一起解决问题并完成版本发布的任务;零信任插件部分,插件的开发让我学习到了较多框架方面的知识,了解了插件的开发以及团队联调的过程,零信任插件的开发在团队帮助下开发较为顺利,并且按时提测,且完成度较高,故障部分相对较少,调整部分基本为业务方面的逻辑调整。工行和标板的需求也是在计划内完成了需求的开发并提测成功,本次绩效期间,工作充实,如期完成了各项需求开发。不足就是多个需求的开发和提测过程相对较慢,由于环境(tac)问题,在开发自测和提测过程中出现了效果不一致的情况,在以后开发中需要注意该方面问题对开发提测的影响,提测前尽量保证自测完整,需求完善。
以上就是本期自我评价。
|