加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
  • 相关推荐
申请入驻 产业图谱

一文搞懂内存泄漏:进程内存段的 “漏洞” 与修复之道

01/13 15:55
312
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

当进程通过malloc申请虚拟内存后,操作系统不会立即为其分配物理内存,而是在首次访问时,才触发缺页异常分配内存。对普通进程来说,能看到的是内核提供的虚拟内存,这些虚拟内存还需要通过页表,由系统映射为物理内存。

为平衡CPU与磁盘间的性能差异,Linux会使用Cache把文件数据缓存到内存中。

内存分配

用户空间内存包括多个不同类型的内存段,比如只读段、数据段、堆、栈以及文件映射段等,下面逐个分析哪些地方可能出现内存泄漏

只读段,包括程序的代码和常量,只读段不会再去分配新的内存,因此不会产生内存泄漏。

数据段,包括全局变量和静态变量,这些变量在定义时就已经确定了大小,也不会产生内存泄漏。

栈内存由系统自动分配和管理,只会出现爆栈或者踩内存情况,超出了局部变量的作用域时,栈内存会被系统自动回收,不会出现内存泄漏情况。

堆内存应用程序自己来分配和管理,如果业务没有正确释放堆内存,就会造成内存泄漏,所以没有特殊情况,尽量使用智能指针管理对象生命周期。

内存映射段,包括动态链接库和共享内存,其中共享内存由程序动态分配和管理。所以如果程序在分配后忘了回收,就会导致内存泄漏。

对于内存泄漏,只能依赖系统OOM机制杀死进程,但是此时已经造成了严重的性能问题,如系统的缓存频繁回收等,会导致业务不可用。

系统命令

top 能观察系统和进程的内存占用情况,vmstat能观察内存的变化趋势。

观察free列,如果一直在减小,说明系统可用内存在变少。可以通过top或ps来观察进程的内存使用情况,然后找出内存使用一直增长的进程,最后再通过pmap分析进程地址空间中内存的使用情况。

使用缓冲区分析工具cachetop分析这些缓存被哪些进程占用;free查看可用内存被哪些进程占用。

cachetop可以分析业务是否有绕过缓存直接读取磁盘,导致读写速度慢;strace可以查看具体的系统调用:

strace -p $(pgrep) PID

检测工具

如果是编码阶段,在上线前检查代码中资源获取的方式,尽量改为智能指针自动管理资源生命周期;禁止系统的swap机制,减少内存和硬盘的交换数据导致性能开销。

如果是调试阶段检查内存泄漏,可以mock掉业务的malloc和free,在malloc/new时将调用方法、申请地址写入指定文件新增一条记录,free时根据地址删除该条记录,在程序运行结束后可以从文件中找到内存泄漏的地方。

bcc中的memleak就是类似思路,利用插桩统计分配的字节和释放的字节,两者进行抵消,而没有释放的调用栈就是可能泄露的地方。

其他内存泄漏检测工具:

AddressSanitizer:速度快,首选;

Valgrind:拦截内存分配和释放函数,无需修改代码,但是速度比较慢;

mtrace:通过环境变量替换malloc和free函数,方便使用。

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录