08 案例篇 | Shmem:进程没有消耗内存,内存哪去了?
该思维导图由 AI 生成,仅供参考
进程没有消耗内存,内存哪去了?
- 深入了解
- 翻译
- 解释
- 总结
Shmem内存泄漏是一种难以观察的内存泄漏类型,因为它不会通过观察进程消耗的内存来进行判断。本文介绍了一种特殊的Shmem——tmpfs,它是一种内存文件系统,存在于内存中,不会体现在进程的内存占用上。作者通过一个真实案例讲述了遇到Shmem内存泄漏的问题,以及如何通过查看/proc/meminfo和df命令来定位和分析Shmem内存泄漏的原因。文章还提到了解决方案,如限制tmpfs大小、定期清理临时日志等。此外,还介绍了其他一些类型的内存,如Slab、KernelStack和VmallocUsed,它们也不会体现在进程内存中,需要在排查内存占用时加以注意。 文章还详细介绍了OOM killer的作用和逻辑,以及如何调整进程的oom_score_adj来影响OOM killer的行为。此外,还讲述了在Kubernetes环境下触发的一个内核Bug,并提到了作者为社区贡献的修复该Bug的patch。 在课堂总结中,强调了对不同内存类型特点的了解对于分析内存问题的重要性,以及如何配置合适的OOM策略来防止重要业务被过早杀掉。最后,提出了课后作业,鼓励读者运行程序并观察oom_score和进程被杀的顺序,以加深对文章内容的理解。 总的来说,本文通过介绍Shmem内存泄漏、OOM killer的作用和调整方法,以及内核Bug的案例,为读者提供了对系统内存问题排查和解决的有益参考。
《Linux 内核技术实战课》,新⼈⾸单¥59
全部留言(11)
- 最新
- 精选
- springchan老师您好, 有一个疑问:tmpfs是一种基于内存的虚拟文件系统,存储空间是在虚拟内存里,重启机器后会丢失,但是我用mmap 在tmpfs下面映射文件以后,通过使用stat 查看tmpfs下面的文件,为什么会占用block 块呢?block 块不是硬盘的空间么?
作者回复: tmpfs是存储在内存中,但是它是使用文件方式来管理的,所以也会有block的概念,它的block size跟page大小是一致的,也是4k,但是tmpfs不是块设备。
2020-09-1711 - 欧阳洲老师好,看完这一讲有两个疑问想请教: (1)tmpfs的特点是快,那么与内存有什么不同呢? 假设一个app只有白天可访问,晚上不提供服务。 白天用tmpfs,晚上再来做耗时的部分:写磁盘,清理tmpfs。 那这样的话,为什么白天不直接存储在内存就好,不必写入tmpfs吧? (2)tmpfs与mmap有什么区别和联系吗,除了mmap属于进程,tmpfs不属于进程之外。
作者回复: 1. tmpfs是内存的一种使用形式,tmpfs里的内容都在内存中。 文件内容在内存中可能会被回收掉,而tmpfs不用担心这个问题;如果你不想被回收,那就需要mlock它。所以tmpfs的优势是使用方便。 2. mmap是接口,tmpfs是存储方式。二者位于不同的层,mmap也可以使用tmpfs,如果进程mmap方式打开tmpfs文件还没有unmap它,那这部分tmpfs内存是属于进程地址空间的。
2020-09-106 - KennyQ有几个问题: 1. 哪些进程会去使用tmpfs? 2. 如何使用tmpfs,是在启动进程的时候把代码嵌入进去?还是说有接口可以调用? 3. tmpfs是怎么被挂载起来的?重启后是否会自动挂载? 4. tmpfs如果被100个进程调用了,会挂载100次么? 5. 启动tmpfs后是否会修改/etc/mtab? 6. tmpfs使用是否有最佳实践? 7. tmpfs是否可以在线扩缩容?
作者回复: 1. 很多应用程序会把日志保存在tmpfs里,也有些应用会把它的运行时文件保存在tmpfs里。比如systemd就会把日志记录到tmpfs中。你可以用mount命令来查看你的系统tmpfs挂载路径,然后去这里面查看有哪些文件,你也可以看出来你的系统里有哪些应用会用到tmpfs. 2. 最简单的使用方式是把tmpfs给mount到一个路径上 然后你的应用往里面写文件就可以使用它了。 3. 通过mount命令来挂载,为了重启后也生效,你可以在启动脚本里来挂载。 4. 不会,只需要挂载一次 然后所有进程都可以用了 使用方式上跟普通文件路径没有差异。 5. 会的。 6. tmpfs的目的是针对那些读写io频繁,但数据量不大的场景。既避免了io,又不浪费太多内存。如果你的业务有这种场景,你可以考虑。 7. 可以的 remount可以改变它的大小。
2020-09-066 - J.Smile要点总结: ①tmpfs ,可以通过 df -h来看是不是 tmpfs 占用的内存较多 ②tmpfs 作为一种特殊的 Shmem,它消耗的内存是不会体现在进程内存中的,这往往会给问题排查带来一些难度。 ③可以通过 /proc/meminfo 找到哪种类型的内存开销比较大,来作为一种辅助手段,比如找到就是tempfs类型的内存,紧接着就可以分析tmpfs的内存占用情况。
作者回复: 总结的不错 赞!
2020-10-111 - qinsi看了下那个patch,为啥原始代码里要把负分给截断阿,是有什么特别的考虑吗
作者回复: 没有特别的考虑,只是因为没有考虑到会存在大量进程设置为负分的这种场景。
2020-09-09 - ray老师您好, 请问我们该怎么判断一个process会不会使用到tmpfs呢? 谢谢老师的解答^^
作者回复: 如果进程打开的tmpfs文件还没有close,那么从进程打开的fd里就能看到这些内存文件(比如通过lsof);如果还没有unmap()掉它从tmpfs里申请的内存,那么从进程的地址空间里是可以观察到这些tmpfs内存的。而如果进程已经close掉了它打开的tmpfs文件,那就无法通过进程来分析了,但是通常tmpfs文件里的文件名都会加上进程的一些相关标记,以方便观察是哪个应用创建的。所以我的建议是,你在使用tmpfs文件时,最好这些文件名能够跟你的业务有些关联。
2020-09-06 - jssfy这个patch很赞!请问老师这个mm oom的bug在centos 7下是否也有?
作者回复: 对的 这个bug在centos7上也存在 可以backport到centos7上。
2020-09-05 - 飞翔我这里有一个这样的问题,服务器集群每隔一段时间就有机器进入死机状态,可以ping通,但是ssh连不上, 这时候就得联系现场人员去重启机器,很麻烦。怀疑是内存耗尽的原因,但是重启机器后,从message日子又看不到证据,oom是不是不一定会释放内存? 这种问题应该怎么定位呢?有什么解决方案呢?
作者回复: 你的内核版本是什么?在老版本内核里,oom如果杀的进程阻塞在内核态的话,比如处于D状态 ,那这个进程的anon内存就没有办法释放;如果是新版本的话,oom会唤醒oom_reaper 然后这个reaper会释放阻塞的进程的内存。所以这类问题的解决方案是,backport oom reaper机制,或者升级内核。定位手段是,你可以使用sysrq -w来看是否这个被杀的进程处于d状态。
2020-09-053 - 冬风向左吹/PROC/MEMINFO之谜:http://linuxperf.com/?p=1422020-09-059
- Linuxer赞!意犹未尽,爽!2020-09-052