Linux 内核技术实战课
邵亚方
前蘑菇街技术专家,Linux Kernel 活跃贡献者
23704 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 26 讲
Linux 内核技术实战课
15
15
1.0x
00:00/00:00
登录|注册

07 案例篇 | 如何预防内存泄漏导致的系统假死?

调整串口打印级别
减少打印信息
OOM相关规避措施
OOM日志相关问题分析
OOM killer选择进程杀掉
内存浪费导致系统内存减少
申请1G内存后不再使用
重新编译并检查内存泄漏
修改程序加上free(p)
进程退出时释放内存
内存泄漏的危害性分析
使用valgrind检查内存泄漏
申请1G内存后未释放
课后作业:构造内存泄漏测试用例
墨菲定律和内存泄漏问题
防止慢速串口接收过多日志
预防内存泄漏及其危害
长时间运行的任务需重视内存泄漏
内存泄漏可能带来严重危害
OOM killer触发
长时间运行的程序内存泄漏
进程地址空间的分配和销毁
简单示例程序演示内存泄漏
课堂总结
如何预防内存泄漏导致的危害?
什么样的内存泄漏是有危害的?
如何预防内存泄漏导致的系统假死

该思维导图由 AI 生成,仅供参考

你好,我是邵亚方。
上节课,我们讲了有哪些进程的内存类型会容易引起内存泄漏,这一讲我们来聊一聊,到底应该如何应对内存泄漏的问题。
我们知道,内存泄漏是件非常容易发生的事,但如果它不会给应用程序和系统造成危害,那它就不会构成威胁。当然我不是说这类内存泄漏无需去关心,对追求完美的程序员而言,还是需要彻底地解决掉它的。
而有一些内存泄漏你却需要格外重视,比如说长期运行的后台进程的内存泄漏,这种泄漏日积月累,会逐渐耗光系统内存,甚至会引起系统假死。
我们在了解内存泄漏造成的危害之前,先一起看下什么样的内存泄漏是有危害的。

什么样的内存泄漏是有危害的?

下面是一个内存泄漏的简单示例程序。
#include <stdlib.h>
#include <string.h>
#define SIZE (1024 * 1024 * 1024) /* 1G */
int main()
{
char *p = malloc(SIZE);
if (!p)
return -1;
memset(p, 1, SIZE);
/* 然后就再也不使用这块内存空间 */
/* 没有释放p所指向的内存进程就退出了 */
/* free(p); */
return 0;
}
我们可以看到,这个程序里面申请了 1G 的内存后,没有进行释放就退出了,那这 1G 的内存空间是泄漏了吗?
我们可以使用一个简单的内存泄漏检查工具 (valgrind) 来看看。
$ valgrind --leak-check=full ./a.out
==20146== HEAP SUMMARY:
==20146== in use at exit: 1,073,741,824 bytes in 1 blocks
==20146== total heap usage: 1 allocs, 0 frees, 1,073,741,824 bytes allocated
==20146==
==20146== 1,073,741,824 bytes in 1 blocks are possibly lost in loss record 1 of 1
==20146== at 0x4C29F73: malloc (vg_replace_malloc.c:309)
==20146== by 0x400543: main (in /home/yafang/test/mmleak/a.out)
==20146==
==20146== LEAK SUMMARY:
==20146== definitely lost: 0 bytes in 0 blocks
==20146== indirectly lost: 0 bytes in 0 blocks
==20146== possibly lost: 1,073,741,824 bytes in 1 blocks
==20146== still reachable: 0 bytes in 0 blocks
==20146== suppressed: 0 bytes in 0 blocks
从 valgrind 的检查结果里我们可以清楚地看到,申请的内存只被使用了一次(memset)就再没被使用,但是在使用完后却没有把这段内存空间给释放掉,这就是典型的内存泄漏。那这个内存泄漏是有危害的吗?
这就要从进程地址空间的分配和销毁来说起,下面是一个简单的示意图:
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入探讨了内存泄漏在软件开发中的危害以及预防措施。作者首先通过示例程序展示了内存泄漏的危害,指出长时间运行的后台进程的内存泄漏会逐渐耗尽系统内存,甚至导致系统假死。文章提到了内存泄漏检查工具valgrind,并通过示例程序演示了如何使用valgrind来检测内存泄漏。作者强调了对于长时间运行的程序,内存泄漏会导致内存浪费,进而影响系统性能。最后,文章提出了解决内存泄漏问题的建议,包括在程序中加入释放内存的操作,以及对后台服务型业务的内存泄漏进行重视和及时处理。整体而言,本文通过具体案例生动地阐述了内存泄漏的危害和预防措施,对于开发人员和系统维护者具有一定的参考价值。文章内容深入浅出,对于读者快速了解内存泄漏问题及解决方案具有指导意义。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Linux 内核技术实战课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(11)

  • 最新
  • 精选
  • 莫名
    valgrind 虽然很强大,但太慢了,推荐 bcc memleak 工具。😀

    作者回复: 嗯 bcc memleak也是个很好的分析工具 就是它对内核版本要求高 需要较新的内核才行

    2020-11-01
    15
  • 不倒翁
    提个见议:案例这方面,教师能否改变一下讲课顺序 运行一个有问题的程序(不看源码)-->观察系统指标发现可能是内存泄漏 -->用工具找到问题程序 -->分析可能是哪方面的问题-->查看源码 -->问题背后的原理等

    作者回复: 谢谢你的建议。这样我也考虑过,只是我们感觉这有点像应试教育先出题再说答案,我主要是担心这会局限住大家的思维。所以我在案例篇里一般都是把具体问题给做一个抽象,能够让大家不局限于某一个问题,而是通过这些抽象的案例来理解问题的本质。

    2020-09-03
    9
  • 大飞哥
    太棒了,谢谢老师!最近项目也出现过假死的现象,lockdep、soft lock等,现在还没找到好的方法去查找和定位,望老师指教。之前也出现过打印日志拉慢系统性能的情况,后面也发现是printk的原因,后面修改printk不从串口输出,打印到网络就解决了,当时也没时间追溯根本原因,现在一想,printk里面有几把锁,是否也是频繁和大数据打印出现锁竞争所导致的?项目需要用到很多特殊硬件资源和DMA,所以大多是内核层开发,成员又很多是从嵌入式应用转过来的,很多问题其实都没找到根因,看到老师专栏,真的受益匪浅!

    作者回复: 在出现这种假死问题时需要首先想办法来保存事故现场,有了这些现场后就可以分析具体原因了,lockdep和softlockup这些都可以认为是内核问题,所以最好可以构造出来vmcore来进行分析,我通常是使用sysyrq来构造出来vmcore,然后分析这些vmcore。这里有个问题时,往往发生问题的时候就没有办法来执行命令了,所以根据一些信息来提前做好预判很重要,比如根据load值达到多少就认为异常了,或者利用其他一些系统指标,比如内存引起的假死可以借助psi指标来做预判。在构造vmcore时,如果是磁盘故障或者文件系统出了问题,那这个vmcore也可能无法保存下来,这个时候借助网络把这些信息给导出来也是一个方案,嵌入式系统中常用的做法这是把他们保存在非易失内存中,然后重启后解析这些非易失内存。

    2020-09-03
    2
    5
  • jssfy
    如果宕机的话kernel buffer的数据可能没来得及落盘,这个一般怎么解?

    作者回复: 异常宕机是总会发生的,如果这个时候有未落盘的数据,那这部分数据就会丢失,这其实是难以去避免的。所以这种问题大致是有两个思路:1.数据没保存完整的话,已保存的数据是准确的就好,文件系统会做校验,不完整的数据认为是无效数据。2. 冗余备份来预防单点故障,一台主机宕机很正常,如果多台同时宕机就几乎不可能了,所以冗余备份是很重要的。

    2020-09-03
    3
  • Wade_阿伟
    关于老师上面提到的,如果进程不是长时间运行,那么即使存在内存泄漏(比如这个例子中的只有 malloc 没有 free),它的危害也不大,因为进程退出时,内核会把进程申请的内存都给释放掉。这里能否理解为进程的内存是由内核通过slab page回收时所释放?

    作者回复: 进程退出时 会去释放进程的地址空间 如果进程地址空间对应的page没有其他人在引用 就会free掉这些page。slab则是只要来管理内核的数据 通常不用来管理进程数据。

    2021-07-25
    2
    1
  • 我能走多远
    第一个例子中只有 malloc 没有 free,它的危害也不大,因为进程退出时,内核会把进程申请的内存都给释放掉。我一直理解的进程退出后,泄露的这块内存也不会被回收掉。真是多年都理解错了。细想了一下,还真是这样,比如我们再开发中会申请一些长期占有的内存。程序挂掉,这些内存就被系统回收掉了。

    作者回复: 对的 程序挂掉后 这些malloc的内存就不再有引用 就会被释放掉。

    2020-10-22
  • 张振宇
    老师,磁盘经常会有文件权限变成??? 的情况,使用xfs repair可以修复,这个是业务的问题吗

    作者回复: xfs存在问题的可能性更大

    2020-09-07
  • 我能走多远
    我是做C开发的,应用层开发内存泄露问题还是比较常见的,有那些好用的方法来快速检测内存泄露问题?
    2020-10-22
    1
    1
  • DoubleYY
    老师最近想做操作系统假死的监控,目前没有思路,应该监控什么指标来实现操作系统假死的监控
    2023-05-05归属地:陕西
  • 未若柳絮
    java程序可以使用 valgrind 吗
    2022-06-30
收起评论
显示
设置
留言
11
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部