专栏首页二狗的DBA之路高性能:8-可用于Memory分析的BPF工具【bpf performance tools读书笔记】

高性能:8-可用于Memory分析的BPF工具【bpf performance tools读书笔记】

内核和处理器负责将虚拟内存映射到物理内存。为了提高效率,会在称为页面的内存组中创建内存映射,其中每个页面的大小是处理器的详细信息。尽管大多数处理器也支持更大的容量,但通常有4 KB,Linux称其为 hugepage大页面。内核可以从其自己的空闲列表中为物理内存页面请求提供服务,内核为每个DRAM组和CPU维护这些请求以提高效率。内核自己的软件也通常通过内核分配器(例如slab分配器)从这些空闲列表中消耗内存。

内存页和交换

典型的用户内存页面的生命周期如图7-2所示,其中列举了以下步骤:

1. 应用程序从内存分配请求开始(例如,libc malloc() )。

2. 分配库可以从其自己的空闲列表中为内存请求提供服务,或者它可能需要扩展虚拟内存来容纳。根据分配库,它将:

1. 通过调用brk() syscall并将堆内存用于分配来扩展堆的大小。

2. 通过mmap() 系统调用创建一个新的内存段。

3. 稍后,应用程序尝试通过存储和加载指令使用分配的内存范围,这涉及调用处理器内存管理单元(MMU)进行虚拟到物理地址的转换。至此,虚拟内存的谎言就暴露出来了:该地址没有映射!这会导致称为页面错误的MMU错误。

4. 页面错误由内核处理,内核建立从其物理内存可用列表到虚拟内存的映射,然后将该映射通知MMU以供以后查找。现在,该过程占用了额外的物理内存页面。进程使用的物理内存量称为其驻留集大小(RSS)。

5. 当系统上的内存需求过多时,内核页面输出守护程序(kswapd)可能会寻找可用的内存页面。它将释放三种类型的内存中的一种(尽管只有(c)如图7-2所示,因为它显示了用户内存页面的生命周期):

1. 从磁盘读取但未修改的文件系统页面(称为“由磁盘支持”):可以立即释放这些页面,并在需要时简单地重新读取。这些页面是应用程序可执行的文本,数据和文件系统元数据。

2. 已修改的文件系统页面:这些是“脏”的,必须先写入磁盘,然后才能释放它们。

3. 应用程序内存页面:由于它们没有文件来源,因此被称为匿名内存。如果正在使用交换设备,则可以先将它们存储在交换设备上来释放它们。将页面写到交换设备称为交换(在Linux上)。

内存分配请求通常是频繁的活动:对于繁忙的应用程序,用户级别的分配每秒可能发生数百万次。加载和存储指令以及MMU查找更加频繁。它们每秒可能发生数十亿次。在图7-2中,这些箭头以粗体显示。其他活动相对较少:brk()和mmap()调用,页面错误和页面退出(较亮的箭头)。

page-out daemon页面输出守护程序

定期激活页面输出守护程序(kswapd)以扫描非活动和活动页面的LRU列表,以寻找可用的内存。如图7-3所示,当空闲内存越过低阈值时它将被唤醒,而当空闲内存越过高阈值时将回到睡眠状态。

kswapd协调后台页面调出;除了CPU和磁盘I/O争用外,这些不应直接损害应用程序性能。如果kswapd无法足够快地释放内存,则会超过可调的最小页面阈值,并使用直接回收;这是释放内存以满足分配条件的前台模式。在这种模式下,分配阻塞(停顿)并同步等待页面被释放。

直接回收可以调用内核模块收缩器函数:这些释放的内存可能保留在缓存中的内存,包括内核slab缓存。

swap devices交换设备

交换设备为内存不足的系统提供了降级的操作模式:进程可以继续分配,但是现在将不常使用的页面移入和移出交换设备,这通常会使应用程序运行得慢得多。

一些生产系统无需交换即可运行;这样做的理由是,对于那些关键系统来说,降级的操作模式是永远无法接受的,因为这些关键系统可能有许多冗余(且运行状况良好)服务器,比开始交换的服务器要好用得多。(例如,对于Netflix云实例,通常就是这种情况。)

如果无交换系统的内存不足,则内核oom killer会牺牲一个进程。为了避免这种情况,将应用程序配置为永不超过系统的内存限制。

oom killer

Linux内存不足杀手是释放内存的最后手段:它将使用启发式方法找到受害者进程,并通过杀死它们来牺牲它们。启发式寻找将释放许多页面的最大受害者,并且这不是关键任务,例如内核线程或init(PID 1)。Linux提供了在整个系统和每个进程中调整OOM杀手的行为的方法。

page compaction页面压缩

随着时间的流逝,释放的页面变得碎片化,从而使内核很难根据需要分配较大的连续块。内核使用压缩程序来移动页面,从而释放连续区域。

file system caching and buffering文件系统缓存和缓冲

Linux借用空闲内存进行文件系统缓存,并在有需求时将其恢复为空闲状态。这种借用的结果是,在Linux启动之后,系统报告的可用内存趋向于零,这可能使用户担心系统实际上只是在预热其文件系统缓存时会耗尽内存。此外,文件系统使用内存进行回写缓冲(write-back buffering)。

可以将Linux调整为更喜欢从文件系统缓存中释放或通过交换释放内存(通过调整参数vm.swappiness)。

传统的分析工具

传统的性能工具提供了许多基于容量的内存使用情况统计信息,包括每个进程和系统范围内使用了多少虚拟和物理内存,以及某些细分,例如按流程段或面板。分析内存使用率超出基本知识,例如页面错误率,分配库,运行时或应用程序对每个分配都需要内置的工具;或者可以使用像Valgrind这样的虚拟机分析器;后一种方法可能会导致目标应用程序在检测时运行速度慢10倍以上。BPF工具效率更高,开销也更小。

Tool

Type

Description

dmesg

Kernel log

OOM killer event   details

swapon

Kernel   statistics

Swap device   usage

free

Kernel   statistics

System-wide   memory usage

ps

Kernel   statistics

Process   statistics, including memory usage

pmap

Kernel   statistics

Process memory   usage by segment

vmstat

Kernel statistics

Various   statistics, including memory

sar

Kernel   statistics

Can show page   fault and page scanner rates

perf

Software   events, hardware statistics, hardware sampling

Memory-related   PMC statistics and event sampling

用于内存分析相关的BPF工具

内存相关的工具:

Tool

Source

Target

Description

oomkill

BCC/BT

OOM

Shows extra   info on OOM kill events显示oom相关的事件

memleak

BCC

Sched

Shows possible   memory leak code paths显示可能的内存泄漏代码路径

mmapsnoop

Book

Syscalls

Traces mmap(2)   calls system-wide跟踪系统范围内的mmap调用

brkstack

Book

Syscalls

Shows brk()   calls with user stack traces显示带有用户堆栈跟踪的brk()调用

shmsnoop

BCC

Syscalls

Traces shared   memory calls with details跟踪共享内存调用的详细信息

faults

Book

Faults

Shows page   faults, by user stack trace通过用户堆栈跟踪显示页面错误

ffaults

Book

Faults

Shows page   faults, by filename通过文件名显示页面错误

vmscan

Book

VM

Measures VM   scanner shrink and reclaim times测量vm scaner的收缩和回收时间

drsnoop

BCC

VM

Traces direct   reclaim events, showing latency跟踪直接回收事件,显示延迟

swapin

Book

VM

Shows swap-ins   by process按进程显示swap情况

hfaults

Book

Faults

Shows huge   page faults, by process按进程显示巨页错误情况

此外,还有几个用于内存分析的BPF工具: kmem 、kpages 、 slabratetop 、 numamove

oomkill

oomkill是一个BCC和bpftrace工具,用于跟踪内存不足杀手事件并打印详细信息(例如平均负载)。平均负载为OOM时的系统状态提供了一些额外的上下文,显示了系统是否正在变得忙碌或稳定。

此输出表明PID 18601(perl)需要内存,这触发了PID 1165(java)的OOM终止。PID 1165的内存占用已达到18006224个pages;这些通常每页4 KB,具体取决于处理器和进程内存设置。loadavg平均负载表明,在OOM终止时,系统变得更加繁忙。

该工具通过使用kprobes跟踪oom_kill_process() 函数并打印各种细节来工作。在这种情况下,只需读取/proc/loadavg即可获取平均负载。调试OOM事件时,可以根据需要增强此工具以打印其他详细信息。此外,此工具尚未使用可以显示有关如何选择任务的更多详细信息的oom跟踪点。

memleak

memleak是一个BCC工具,可跟踪内存分配和空闲事件以及分配堆栈跟踪。随着时间的流逝,它可以显示长期幸存者-尚未释放的分配。

此示例显示了在bash shell进程上运行的memleak:

仅memleak不能告诉您这些分配是否是真正的内存泄漏(内存泄漏:指的是没有引用并且永远不会释放的已分配内存),内存增长还是长期分配。为了区分它们,需要研究和理解代码路径。

当然,还有很多内存分析的小工具。这里就不一一列举了。具体可以看brendangregg大佬的新书。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 运维DBA的4大纪律9项注意【转】

    甭管你是团队,还是团伙,要求都是一样的,一切行动听指挥!听谁的指挥?听运维经理、运维总监、CTO、CEO的指挥。

    二狗不要跑
  • graphite在centos7上的部署搭建

    部署python的程序推荐使用virtualenv这列的虚拟环境来进行,防止污染系统自带的python包。

    二狗不要跑
  • proxysql 开启http监控页面的方法

    官方文档地址: https://proxysql.com/blog/proxysql-http-server-initial-release

    二狗不要跑
  • 存储器及其管理方式

    “计算机存储器包括主存和辅存,本文中存储器管理的对象主要是主存,也称内存。它的主要功能包括分配和回收主存空间、提高主存利用率、扩充主存、对主存信息实现有效保护。...

    搬砖俱乐部
  • Android内存管理(三)内存管理基础

    CPU只能访问其寄存器(Register)和内存(Memory), 无法直接访问硬盘(Disk)。存储在硬盘上的数据必须首先传输到内存中才能被CPU访问。从访问...

    Anymarvel
  • 在物理内存中观察CLR托管内存及GC行为

    虽然看了一些书,还网络上的一些博文,不过对CLR托管内存细节依然比较模糊。而且因为工作原因总会有很多质疑,想要亲眼看到内存里二进制数据的变化。

    lulianqi
  • 技术分享 | MySQL 内存管理初探

    本文来源:原创投稿 *爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

    爱可生开源社区
  • 内存疯狂换页!CPU怒批OS

    我是CPU一号车间的阿Q,前一阵子我们厂里发生了一件大喜事,老板拉到了一笔投资,准备扩大生产规模。

    轩辕之风
  • ElasticSearch优化系列二:机器设置(内存)

    预留一半内存给Lucence使用 一个常见的问题是配置堆太大。你有一个64 GB的机器,觉得JVM内存越大越好,想给Elasticsearch所有64 GB的内...

    用户1332428
  • 经典面试题-GC是什么,为什么要有GC

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    cwl_java

扫码关注云+社区

领取腾讯云代金券