内存泄漏的原因?
常见的导致内存泄漏的原因:
-
未释放动态分配的内存
-
丢失对动态分配内存的指针
-
循环引用
-
资源管理错误
-
异常情况下的错误处理
-
缓存未清理
内存泄漏是在没有自动 gc 的编程语言里面,经常发生的一个问题。因为没有 gc,所以 分配的内存需要程序员自己调用释放。其核心原因是调用分配与释放没有符合开闭原则, 没有配对,形成了有分配,没有释放的指针,从而产生了内存泄漏。
GC(Garbage Collection)是一种自动内存管理技术,它负责自动检测和回收程序中不再使用的内存,从而减轻开发人员手动管理内存的负担。在GC编程中,开发人员不需要显式地分配和释放内存,而是依靠垃圾回收器自动处理内存的分配和释放。
内存泄漏如何解决?
解决方案一,引入 gc。这是根治内存泄 漏的最好的方案。但是这样的方案有失去了 c/c++语言的优势。
方案二,当发生内存泄漏 的时候,能够精准的定位代码哪一行所引起的。这也是我们实现内存泄漏检测的如何核心实现需求。
内存泄漏是由于内存分配与内存释放,不匹配所引起的。
需求 1:能够检测出来内存泄漏
需求 2:能够判断是由代码哪一行引起的内存泄漏
解决思路:对内存分配函数,以及内存释放 free 进行“劫持”hook。能够统计出内存分配的位 置,内存释放的位置,从而判断是否匹配。比如malloc时创个文件,free时删除文件。如果程序最后文件夹有文件代表代码存在内存泄漏。
代码如下
openff/memleak: 内存泄露检测 (github.com)
gdb调试如何发现内存泄漏?
函数调用前和调用后,调用系统函数,看主要关注值是否一致。不一致则内存泄漏
(gdb) n
22 test_malloc_leak(1024);
(gdb)call malloc_stats() //调用test_malloc_leak函数前查看内存
Arena 0:
system bytes = 135168 //主要关注
in use bytes = 73376 //主要关注
Total (incl. mmap):
system bytes = 135168 //主要关注
in use bytes = 73376 //主要关注
max mmap regions = 0
max mmap bytes = 0
(gdb) n
23 return 0;
(gdb) call (void)malloc_stats()
Arena 0:
system bytes = 135168
in use bytes = 74416 //值不一致 说明test_malloc_leak存在内存泄漏
Total (incl. mmap):
system bytes = 135168
in use bytes = 74416
max mmap regions = 1
max mmap bytes = 10489856
xml形式形式输出
(gdb)call malloc_info(0,stdout)
<malloc version="1">
<heap nr="0">
<sizes>
</sizes>
<total type="fast" count="0" size="0"/>
<total type="rest" count="1" size="60752"/> //主要关注
<system type="current" size="135168"/>
<system type="max" size="135168"/>
<aspace type="total" size="135168"/>
<aspace type="mprotect" size="135168"/>
</heap>
<total type="fast" count="0" size="0"/>
<total type="rest" count="1" size="60752"/>
<total type="mmap" count="0" size="0"/>
<system type="current" size="135168"/>
<system type="max" size="135168"/>
<aspace type="total" size="135168"/>
<aspace type="mprotect" size="135168"/>
</malloc>