“快、准、狠” 地找到系统内存瓶颈

1. 内存性能指标

首先,最容易想到是系统内存的使用情况,比如已用内存、剩余内存、共享内存、可用内存、缓存和缓冲区的用量等。

  • 共享内存,通过tmpfs实现,它的大小就是tmpfs使用的内存大小,tmpfs也是一种特殊的缓存。、
  • 可用内存是新进程可以使用的最大内存,包括剩余内存和可回收内存。
  • 缓存,包括两部分:一部分是磁盘读取文件的页缓存,用来缓存磁盘读取的数据,可以加快以后再次访问速度;另一部分是Slab分配器中的可回收内存。
  • 缓冲区则是对原始磁盘块的临时存储,用来缓存将要写入磁盘的数据。

其次,是进程的内存使用情况,比如进程的虚拟内存,常驻内存、共享内存以及Swap内存等。

  • 虚拟内存,包括进程代码段、数据段、共享内存、已申请的堆内存、已换出的内存等。注意,已申请的内存,即使还没有分配物理内存,也是虚拟内存。
  • 常驻内存,进程实际使用的物理内存,不包括Swap和共享内存。
  • 共享内存,包括与其他进程真实的共享内存、加载的动态库以及程序代码段等。
  • Swap内存,通过Swap换出到磁盘的内存。

这里另外强调一下,缺页异常,分为以下两种场景:

  • 可以直接从物理内存分配的,次缺页异常。
  • 需要磁盘I/O介入(比如Swap)的,主缺页异常。主缺页异常升高,需要磁盘IO,内存访问会变慢。

最后一种,Swap的使用情况,比如已用空间、剩余空间、换入换出速度(每秒换入换出的内存大小)等。

请看下面思维导图:

                                   

2. 性能工具以及与性能指标的联系

free:查看系统整体内存和 Swap的使用情况。

top 或 ps:查看进程的内存使用情况。

vmstat:动态观察内存变化情况,区分了缓存和缓冲区、Swap的换入换出的内存大小。

cachestat:查看整个系统缓存的读写命中情况。

cachetop:查看进程缓存的读写命中情况。

memleak:给出内存分配栈,找出内存泄漏的可能位置。

sar:内存和 Swap的使用情况。

proc文件系统:/proc/meminfo、/proc/pid/status、/proc/pid/smaps。

     

3. 如何快速分析内存的性能瓶颈

为了迅速定位内存问题,通常会先运行几个覆盖面比较广的性能工具:free、top、vmstat、pidstat等。

具体的分析思路一般分为这几步:

先用 free 和 top查看系统身整体内存使用情况;

再用 vmstat 和 pidstat,查看一段时间的趋势,从而判断内存问题的类型;

最后详细分析,比如内存分配分析、缓存 / 缓冲区分析、具体进程的内存使用分析等。

下面展示了分析过程的一个流程图:

              

举三个典型类型的例子说明一下这个流程图:

第一个例子,free 发现大部分内存被缓存占用,可使用vmstat 或 sar 缓存变化趋势,确认缓存是否继续增大。如果是,说明导致缓存增大的进程还在继续,那就能用cachetop 或 slabtop 分析,缓存到底被哪里占有。

第二个例子,free 发现系统可用内存不足,首先确认内存是否被 buff/cache占用。如果能排除掉这个原因,那就继续用pidstat 或 top定位占用内存的进程,找出后再用内存空间工具(如pmap),分析进程地址空间中内存的使用情况。

第三个例子,当通过vmstat 或 sar 发现内存内存在不断增长后,检查是否存在内存泄漏,再用memleak  或者 valgrind工具

常见的几种优化思路:

  • 最好禁止Swap,如果实在需要开启,就调低 swappiness 的值,减少内存回收时Swap使用倾向。
  • 减少内存的动态分配,可以使用内存池或者大页(HugePage)等。
  • 尽量使用缓存 / 缓冲区访问数据。比如,可使用堆栈明确声明内存空间,来存储需要缓存的数据;或者用Redis这类外部缓存组件,优化数据访问。
  • 使用 cgroup等方式限制进程的内存使用情况,可确保系统内存不会被异常进程耗尽。
  • 通过 /proc/pid/oom_adj,调整核心应用的 oom_score ,可保证即使出现内存紧张的情况,核心应用也不会被OOM机制杀死。

以上是工作之余的学习总结,因CSDN网站的变态要求,这里不能提供内容来源。

发布了37 篇原创文章 · 获赞 20 · 访问量 4935

猜你喜欢

转载自blog.csdn.net/qq_24436765/article/details/103888124