MM 事件 - 历史内存统计信息

在发布时搭载 Android 12 及更高版本的设备可以使用 mm_events,这是一组在系统遇到内存压力时定期捕获的内存相关统计信息。mm_eventsperfetto 跟踪机制集成,因为它仅在检测到内存压力时才会激活,因此可以尽量避免增加性能开销。统计信息的收集会在内核的 kswapddirect reclaim,compaction 机制激活时开始,并在可配置的时间段内保持活跃状态,定期捕获统计信息。

mm_events 不会在提交 bug 报告时提供系统内存状态的一次性快照,而是会显示内存压力存在期间内存统计信息的简要历史视图。下表列出了捕获的统计信息。

vmstat 字段

nr_free_pagesnr_slab_reclaimable
nr_slab_unreclaimablenr_active_file
nr_inactive_filenr_active_anon
nr_inactive_anonworkingset_refault
workingset_activatenr_file_pages
pgpginpgpgout
pswpinpswpout
pgsteal_kswapd_dmapgsteal_kswapd_normal
pgsteal_kswapd_movablepgsteal_direct_dma
pgsteal_direct_normalpgsteal_direct_movable
pgscan_kswapd_dmapgscan_kswapd_normal
pgscan_kswapd_movablepgscan_direct_dma
pgscan_direct_normalpgscan_direct_movable
compact_migrate_scannedcompact_free_scanned

与 mm 相关的跟踪事件

vmscan/mm_vmscan_kswapd_wakevmscan/mm_vmscan_kswapd_sleep
vmscan/mm_vmscan_direct_reclaim_beginvmscan/mm_vmscan_direct_reclaim_end
compaction/mm_compaction_begincompaction/mm_compaction_end

分析 mm_events 数据

如果启用了 mm_events,在设备开始经历高内存压力后不久捕获的事件的 bug 报告会在 FS/data/misc/perfetto-traces/bugreport/systrace.pftrace. 中提供 mm_events 历史统计信息(采用压缩报告形式)。

您可以使用 Perfetto 界面查看 vmstat 数据和 ftrace 事件,进而进行分析。

vmstat 数据

systrace.pftrace 文件上传到 Perfetto 界面,查看时间轴上绘制的 vmstat 数据图表,如下所示。

时间轴上绘制的 vmstat 数据图表

图 1. vmstat 图形数据的时间轴

ftrace 事件

捕获的 ftrace mm_events 未在时间轴上以图形方式显示。如需查看它们,请点击 Query SQL 标签页,如图 2 所示。

找到“Query SQL”标签页,然后点击查看已捕获并绘制成图表的 ftrace 和 mm_events

图 2. 点击“Query (SQL)”进行访问

启用 mm_events

如需启用 mm_events,请在供应商 init.rc 中设置 sysprop persist.mm_events.enabled=true

我们采取了以下措施,以减少 mm_events 的内存和 CPU 占用空间:

  • mm-events ftrace 实例为每个 CPU 使用 4KB 缓冲区。
  • kmem_activity 触发器的速率限制为每分钟一次。
  • 任何时候都只能有 1 个 mm-events 跟踪会话处于活跃状态。

自定义

mm_events 使用 perfetto 跟踪配置文件来指定要在跟踪会话期间捕获哪些统计信息。

您可以在 /vendor/etc/mm_events.cfg 中提供自定义 Perfetto 跟踪配置。有关可用的跟踪配置字段的说明,请参阅 Perfetto 文档。如需查看跟踪配置示例,请参阅这个 mm_events.cfg 示例。

以下代码段显示了要添加到跟踪配置以确保它由内存压力触发的重要字段。

# Ensures only 1 tracing session with this key can be active
unique_session_name: "perfetto_mm_events_session"

# If a trace with bugreport_score > 0 is running,
# the captured data is made available in the zipped bugreport
# at FS/data/misc/perfetto-traces/bugreport/systrace.pftrace
bugreport_score: 100

trigger_config {
  trigger_mode: START_TRACING
  trigger_timeout_ms: 3600000   # 1 hour
  triggers {
    # kmem_activity trigger gets activated when memory pressure
    # is detected
    name: "kmem_activity"
    stop_delay_ms: 360000       # 6 mins
  }
}

在这个配置中,mm_events 会启动 perfetto kmem_activity 触发器,并且 Perfetto 跟踪会话会开始捕获 vm_statsftrace 内存事件,直到配置的 stop_delay_ms 时间段(36000 毫秒,即 6 分钟)结束。触发器超时设置为较大的值(在本示例中为 1 小时),并且系统会定期重新开启 mm_events config,以确保始终启用 mm_events。因此,系统会生成一份 bug 报告,其中包含图 1图 2 中所示的那类数据。