排查内存使用(泄露、耗尽)问题的一个的技巧是,区分“批发商”和“零售商”这两类不同的内存管理机制。这里的“批发商”,指的是按页面管理并分配内存的机制。而“零售商”,则是指从“批发商”那里批量获取资源,并以字节为单位,管理和分配内存的机制。

“零售商”和“批发商”的区分很重要。这是因为通过“零售商”分配出去的内存资源,在“批发商”那里或多或少都有统计。但是从“批发商”那边分配出去的内存资源,“零售商”几乎一无所知。凡是一些诡异的,“我的内存去哪里了”的问题,往往都跟这个有点有关系。

“批发商”“零售商”的例子很多,比如Windows上的一对接口VirtualAlloc和HeapAlloc。而在Linux内核中,buddy system毋庸置疑是最大内存的“批发商”,而slab则是最常用的“零售商”。今天这篇文章,我跟大家分享一个和“零售商”slab有关的真实案例。

云监控是一个好产品

今天的案例,我们从云监控说起。云监控作为一个监控工具,给客户提供了非常丰富的功能。阿里云的客户可以使用云监控来随时了解云服务的状态,而且在云服务出现异常的时候,客户可以及时地收到来自云监控的报警信息。

做为阿里云技术支持的同学,可以说我们对云监控有着一种非常“特殊”的感情。这是因为,很多时候客户提给我们的问题,会以一个云监控的截图开始,看到云监控的截图,那基本就等于我们有新的问题需要处理了。

以上的截图是云监控通过钉钉消息发送给客户的报警信息。从这个截图里来看,客户的一台ECS实例内存使用率超过了90%,而且持续了1分钟时间。这对ECS服务器来说,是相当不健康的状态。

基本套路

处理内存使用问题,有一些基本套路。首先,我们可以使用free或top命令看一下系统总体内存使用情况,如物理内存大小,有多少剩余内存,有多少被cache(这里的cache和slab机制的cache是两回事)和buff用掉了;其次,我们可以使用ps命令看看每个进程内存的使用情况;如果到这一步还没有定位到问题,进一步,我们可以通过查看/proc/meminfo文件,在更细的粒度上了解内存资源的分布与分配情况。按照这个套路打下来,一般我们都会得到一个初步的排查结果。以今天这个问题为例,系统32G内存几乎被用光了,但是cache和buff并不大,进程使用的内存也不多。最终在meminfo文件中,我发现有大量内存被slab用掉了。

零售商slab

Slab应该算是Linux内存管理机制中,最著名的“零售商”机制。写slab的文章非常多,我这里只做简单的介绍。

做为“零售商”,slab肯定需要解决两个问题,一个是怎么样从“批发商”buddy system那里“批发”内存,另外一个是怎么样管理并把这些内存“散卖”出去。为了回答这两个问题,我们首先理解一下slab机制的数据结构。Slab机制包括三个层次的数据结构:cache,slab和object。如下图,一个slab一般是一个4K大小的内存页面。当我们把slab页面,按照固定大小切分成能够被“零售”的小块的时候,我们就得到了很多的object。当把包含相同大小object的slab用“箭头”串起来的时候,就形成了cache。这里slab和object是比较容易理解的:因为把4K的页面分配给几个字节的对象使用太浪费内存了,所以就需要切开来“散卖”。而cache的存在意义其实是比较隐晦的。Cache存在的意义,其实是为了动态的管理slab,让slab可以动态的增加和减少。在object需求量大的时候,可以从“批发商”那里拿到很多的slab放进cache里,而在用完之后,又可以动态地把slab退回去。

基于cache, slab和object数据结构,slab机制要解决上边那两个问题就变得很容易了:一方面,slab机制从“批发商”buddy system那里,以slab(页面)为单位获取内存;另外一方面,slab机制以object为基本管理单元,把内存资源“零售”给系统中其他模块。

Slabtop是一个可以用来查看slab内存使用情况的工具。下边这个截图来自客户问题现场。我们可以根据cache size这一列,快速地定位到问题。很明显cache size最大的一行对应的对象是dentry。

注意:为了解释简单,这里我假设slab是一个页面,也就是4K大小。这个假设意味着,所有被管理的对象都是小于4K的。但在实际情况中,为了提供大于4K的内存块,一个slab其实可以是多个连续的物理页面。

小对象搞出大事情

目录项dentry算是一个非常小的内核数据结构。从上边的截图我们可以看到,dentry其中只有0.19K。虽然dentry很小,但是这个结构是内核中最常使用的数据结构。如下图,当进程打开文件的时候,一般都会有对应的dentry被分配出来。在Linux这样的“一切皆文件”的操作系统里,dentry结构被使用频率是不言自明的。

因为已经定位到了内核数据结构dentry,所以我选择抓一个dump来慢慢分析这个问题。抓了dump之后让客户重启机器释放内存,以免导致更严重的后果,影响业务。

Core dump掘金

使用core dump排查问题有两个优势:一是在生产环境中,客户有时候真的很难给我们机会去使用一些trace和工具一步一步的排查问题,而抓dump对业务的影响较小,抓完之后可以慢慢分析。二是core dump里包含了系统中所有正常、不正常的状态。数据量大且完整,这不是一般的数据收集方法可以比的。下边我演示一遍怎么用core dump来排查slab泄露问题。

系统基本信息

使用sys命令,我们可以快速看一下客户这台机器的基本信息。如机器名,内核版本,内存大小等。

内存概要

因为这个问题是内存使用问题,我们可以用kmem -i命令在dump里看一下内存的使用情况。我们可以看到,这个系统有32G内存,其中slab用掉27G。

Cache

接下来我们看一下slab的使用情况。命令kmem -s可以帮我们列出内核中所有的slab cache。如下图,每一行对应一个cache,每个cache负责管理一个对象,第二列是对象的名字。

Slab

既然已经发现了问题是由dentry对象引起的,那么,我们可以到slab结构内部去查看泄露的的dentry。命令kmem -S dentry可以帮我们列出包含dentry的所有slab。可以对照“零售商slab”一节第一个插图来看下边的截图。前两行给出了cache的一些基本信息,如地址,object名字,object大小等。从第三行开始,这个命令分块输出cache中所有的slab结构。每个slab里包含一列小对象,这些对象都在一个页面内部,从他们连续的地址可以看出这点。实际上这个系统分配了7百万slab页面给dentry,下图只截了前两个。

小对象dentry

这个时候问题来了。这个cache里有7百万slab,有1亿4千万dentry项,我们怎么去分析这些项呢?其实有一个很简单的技巧,就是随机挑选的一些dentry,然后看看这些dentry项里,有没有什么共同的特征,比如相同的字符串,或者共同引用的地址等。对这个问题来说,我是很幸运的。我发现在随机挑选的dentry结构里,d_iname这个字符串都包含一个子串“dOeSnotExist_.db”。

使用dOeSnotExist_.db这个子串,我们可以在公网上轻而易举地定位到下边这个问题:这是nss-softokn软件包的一个Bug。

后记

技术支持工作的一个创新点,也是这个工种的一大乐趣,是可以利用各种组合技,利用不同的方法,巧妙地组合并找出问题的答案。以今天这个问题为例,我们开始使用了一些基础的排查工具对问题进行了初步的定位;进而我们使用了core dump这种看起来不那么易用的工具,从内存中挖出了一个字符串作为线索;最后结合公网上的信息,我们拼出了这个问题的答案。

本文作者:声东
阅读原文
本文为云栖社区原创内容,未经允许不得转载。

Slab,小对象也能搞出大事情相关推荐

  1. JVM中GC小对象配置

    小对象配置 -XX:+UseTLAB 表示,使用TLAB TLAB Thread Local Allocation Buffer 线程本地分配缓存 一个线程专用的内存分配区域,为了加速对象分配 每一个 ...

  2. Redis存储优化--小对象压缩

    小对象压缩 Redis是一种内存数据库,内存是计算机中一种比较宝贵的资源,如果我们不注意节约,Redis很可能出现内存不足,最终导致崩溃.Redis为了优化数据结构的内存占用,增加了非常多的优化点,这 ...

  3. Java小对象的解决之道——对象池(Object Pool)的设计与应用

    一.概述 面向对象编程是软件开发中的一项利器,现已经成为大多数编程人员的编程思路.很多高级计算机语言也对这种编程模式提供了很好的支持,例如C++.Object Pascal.Java等.曾经有大量的软 ...

  4. PS 2019 Mac版 自学入门系列(九)—— 复制小对象和纹理

    学习内容--使用仿制图章工具以复制小对象和纹理 目录 学习内容--使用仿制图章工具以复制小对象和纹理 1. 图像处理前后对比 2. 使用仿制图章工具 3. 图像处理结果 1. 图像处理前后对比 处理目 ...

  5. HBase技术与应用实践 | HBase2.0重新定义小对象实时存取

    本次分享来自中国HBase技术社区第七届MeetUp成都站,分享嘉宾天引 阿里巴巴 技术专家专注在大数据领域,拥有多年分布式.高并发.大规模系统的研发与实践经验,先后参与HBase.Phoenix.L ...

  6. linux常见命令汇总

    1. ls ls -l -R /home/peidachang   列出/home/peidachang文件夹下的所有文件和目录的详细资料 ls -l t*   列出当前目录中所有以"t&q ...

  7. 对象检测目标小用什么模型好_小目标检测技术分析

    小目标检测技术分析 小目标检测及跟踪系统分为四个模块: · 硬件模块 该模块基于标准PCI总线,并配以超大规模可编程芯片(DSP.FPGA),具有极强的运算.处理能力. · DSP 程序模块 其功能主 ...

  8. Linux slab 分配器剖析

    简介: 良好的操作系统性能部分依赖于操作系统有效管理资源的能力.在过去,堆内存管理器是实际的规范,但是其性能会 受到内存碎片和内存回收需求的影响.现在,Linux® 内核使用了源自于 Solaris ...

  9. slab 内存分配器介绍(一)

    原文引用地址:https://www.ibm.com/developerworks/cn/linux/l-linux-slab-allocator/ 动态内存管理 内存管理的目标是提供一种方法,为实现 ...

最新文章

  1. hdu 1516(编辑距离+记录路径)
  2. Docker(一)Centos7.0安装Docker
  3. 《编程珠玑(续)(修订版)》—第2章2.1节Awk中的关联数组
  4. 省一计算机考试题库Excel,计算机等级考试省一级省计算机等级考试题库.doc
  5. 2013年6月12日星期三
  6. Java 类型信息 —— 获取泛型类型的类对象(.class)
  7. python 并发编程 多线程 守护线程
  8. 如何在matlab中建立水箱模型_水箱
  9. java wsimport https,wsimport使用小结二
  10. 连接服务器失败是什么原因
  11. 亲身经历,大龄程序员,为什么难找对象!
  12. 解决64位虚拟机安装和键盘FN快捷键问题
  13. Quick MTF,镜头图像质量测试应用程序
  14. 微信speex音频格式转mp3
  15. 输入十进制数字,中文大写数字的形式读出
  16. CCNA实验二十四 路由更新的安全
  17. OPM Demo Flow
  18. C语言程序设计孙家啸第一版,4月广东省高等教育学考试各专业课程使用教材.doc...
  19. linux 图形界面 文件压缩/解压缩 归档管理器 简介
  20. 【GPU】显卡算力对比表

热门文章

  1. 4.9.3 方法注释
  2. Scala swing和FX
  3. 博客园网站程序的一个小问题
  4. 王树彤IT美女七年磨一剑
  5. 版本控制8(译文) -(完)
  6. 百度之星度度熊与邪恶大魔王
  7. Spark的RDD分区器
  8. 【UE4】二十三、UE4笔试面试题
  9. Hbase 常见错误总结——摘自忘了
  10. 应用 TransactionScope 报:此操作对该状态的事务无效 的错误