当前位置:首页 > 内存 > 正文

oom内存泄漏排查原因

  • 内存
  • 2024-06-09 13:35:37
  • 1363

一、cgroup内存泄露问题排查记录发生内存泄漏的主机是一台运行了5天左右的集群计算机,内存利用率在90%以上。其上运行集群管理软件和docker,运行测试脚本反复启动和停止容器文件。
经过长时间的运行,集群主机的内存占用逐渐增加,出现应用程序OOM现象。
实际检查时发现主机总内存使用率较高,但应用程序实际内存使用率较低或未发现明显异常。
可以看到内存使用率为83.6%,而上面显示的实际内存使用率最多只有0.6%。没有占用太多内存的应用程序。
内存占用除了用户应用占用之外,还包括内核占用,所以要检查内核内存占用。
使用Linux文件系统界面查看
可以看到占用率极高的项被slab内核占用了:
继续查看详细的内核占用情况,按照缓存大小排序
可以在这里看到:
kmalloc-2048,kmalloc-4096,kernfs_node_cache,kmalloc-1024,kmalloc-192,kmalloc-512都占据较大的面积。高与正常主机相比,远远超出了正常值。
如果内核缓存过高,可以尝试释放内核缓存:
但是执行上述操作后,内存使用量仍然没有减少显着,这也与上面看到的SUnreclaim的不可回收内存的大小一致。该内存无法释放。
kmalloc是内核分配的内存,最有价值的参考就是kernfs_node_cache占用率高,所以搜了一下这一项的能。
显然,这个现象是内核使用率大大超标,所以我在搜索时添加了关键字memoryleak,很快就发现了Issuesdocker-run--memoryslabcacheleakoncentos7
这个问题说明centos7被重复执行运行dockerrun--rm--memory1ghello-world时,内核内存使用量大幅增加且无法释放。而且这个现象和现在的现象是一致的。
最终表明kernelcgroup内部内存泄漏问题slableakcausingacrashwhenusingkmemcontrolgroup
一般原因是在kernel3.10上使用kmemlimit参数,导致cgroup回收时部分分配的内存无法释放。至于更深入的了解,首先需要花更多的时间来解决当前的问题。
原因可能已经确定。再次确定问题,如果用上面的方法能够修复,就可以确定是问题所在。
在只运行docker的机器上执行上面的语句,查看该盘的内存使用情况。可以看到内存使用量显着增加。并且最终的表现与现有环境的问题是一致的。总内存使用率高,用户态内存使用率低,内核内存使用率高且无法释放。
由于这是内核问题,并且已知明确的复发路径,因此可以通过两种方式解决:
最后经过测试,我选择更改内核版本,Ubuntu18.04将作为新的操作系统。
Linux内核采用分层内存管理方法,每个级别解决不同的问题。从下到上的关键部分如下:
Slab是Linux操作系统的一种内存分配机制。它的工作是针对一些经常分配和释放的对象,例如进程描述符。这些物体的尺寸一般都比较小。如果直接使用伙伴系统来分配和释放,不仅会造成很多内部碎片问题,而且处理速度也会太慢。板分配器是基于每个对象进行处理的。相同类型的对象被分为一个类别(例如,进程描述符就是一个类别)。每当请求该类型的对象时,板分配器就从板列表中分配该大小的对象。驱动器退出,当需要释放它时,它会被保存回该列表,而不是直接返回到合作伙伴系统,从而避免这些内部碎片。lab分配器不会丢弃分配的对象,而是释放它们并将它们存储在内存中。以后请求新的对象时,可以直接从内存中获取,而不必重复初始化。
Slab占用内存过高。Slab可以手动删除可回收缓存,操作如下:
drop_caches的四个值含义如下:
二、前端vue项目内存泄漏排查总结内存泄漏(MemoryLeak):未使用的内存无法及时释放。要执行的程序大于可用内存。
issueskeep-alive内存溢出
提交源代码修改问题
源代码修改部分
keep-alive组件源代码部分:
vue@2.6.10
vue@2.6.13新的cacheVNode方法
这里oCache=null删除了vnode引用和旧版本的cache[key]=vnode不会执行此操作。
这里的缓存只需要三个参数:组件的名称;如果存储了标签和实例组件实例引用。缓存不会被释放。
Keep-alive是一把双刃剑,用得好可以提升用户体验;好处则相反。