Filemap 文件页堆栈抓取

工具抓取

名称:filemap

地址:https://kpan.mioffice.cn/webfolder/ext/9uIEwyskjiT%24uVm31GQvyw%40%40?n=0.9258364536417749

密码:Uc26

adb push filemap_catch /data/local/tmp
adb shell
su # 需 root 手机
cd /data/local/tmp/
chmod +x filemap_catch
./filemap_catch -p com.android.systemui -s -d
...
# 执行完成后
exit  # su 执行两次
adb pull /data/local/tmp/filemap.perf.data .
adb pull /data/local/tmp/filemap_inode.json .

filemap_catch 命令说明

  • -p 进程名
  • -t perf 抓取时间
  • -m 内核态内存大小,如果内核态丢失率高可提高该参数,大小需 2 的 n 次方,如果有 out of memory 错误需降低该参数
  • -u 用户态内存大小,如果用户态丢失率高可提高该参数
  • -s 通过停止 Android 的方式去抓取,系统自启动进程使用,非系统进程可不使用,默认是 stop 进程抓取
  • -d dump inode 文件
  • -k 通过杀进程的方式去抓取,自启应用一般会丢失一些数据,尽量不使用
/data/local/tmp/ # ./filemap_catch -h
Usage: filemap_catch -p <target_process> [-t <duration>] [-m <mem_map>] [-o <outfile>] [-s | -k]
Options:
  -p <target_process>  Target process name
  -t <duration>        Duration of perf data collection (default: 10)
  -m <mem_map>         Memory map size (default: 65536)
  -u <user_mem>        User buffer size (default: 1024M)
  -o <outfile>         Output perf data file (default: /data/local/tmp/filemap.perf.data)
  -d                   Dump inode file (path: /data/local/tmp/filemap_inode.json)
  -s                   Stop Android before catch (default: stop process)
  -k                   Kill target process before catch

如果有文件被多个进程使用,请考虑停止这些进程,例如:

pm disable com.miui.weather2
pm disable com.miui.miwallpaper
lsof | grep libllvm-qgl.so  # 这里查看就剩一个 systemui 后再执行命令抓取
./filemap_catch -p com.android.systemui -s -d

以下是手动执行命令抓取,建议使用工具抓取

自启动应用

以 systemui 为例,需要手机有 root 权限

  1. 停止 android 系统
adb shell stop
  1. 执行 drop cache
adb shell "echo 3 > /proc/sys/vm/drop_caches"
  1. 执行 simpleperf 抓取命令后(执行 filemap 申请命令即可),同时执行步骤 4
# filemap 申请
adb shell "chrt -f 10 simpleperf record -g --app com.android.systemui --duration 10 -e filemap:mm_filemap_add_to_page_cache -c 1 -m 65536 --cpu-percent 99 --user-buffer-size 1536M -o /data/local/tmp/filemap.perf.data"
 
# 如果遇到 Out of memory 错误可调整 -m 值大小
# -m 值需是 2 的 n 次方
 
# 如果 start 启动时 simpleperf 被杀掉可以尝试如下方式
adb shell
echo 3 > /proc/sys/vm/drop_caches && kill -9 `pidof com.android.systemui` && echo 3 > /proc/sys/vm/drop_caches && chrt -f 10 simpleperf record -g --app com.android.systemui --duration 10 -e filemap:mm_filemap_add_to_page_cache -c 1 -m 65536 --cpu-percent 99 --user-buffer-size 1536M -o /data/local/tmp/filemap.perf.data
 
# 对于一些 so 库共享的文件,可以通过 pm disable 关闭其他自启应用
adb shell
pm disable com.miui.weather2
pm disable com.miui.miwallpaper
lsof | grep libllvm-qgl.so
echo 3 > /proc/sys/vm/drop_caches && kill -9 `pidof com.android.systemui` && echo 3 > /proc/sys/vm/drop_caches && chrt -f 10 simpleperf record -g --app com.android.systemui --duration 10 -e filemap:mm_filemap_add_to_page_cache -c 1 -m 65536 --cpu-percent 99 --user-buffer-size 1536M -o /data/local/tmp/filemap.perf.data
# filemap 释放,释放会有其他进程释放,不是非常准确
adb shell "chrt -f 10 simpleperf record -g --app com.android.systemui --duration 10 -e filemap:mm_filemap_delete_from_page_cache -c 1 -m 65536 --cpu-percent 99 --user-buffer-size 1536M -o /data/local/tmp/filemap.perf.data"
  1. 启动 android 系统
adb shell start
  1. 等待 simpleperf 抓取完成后抓取 showmap 和 meminfo 并导出数据
adb shell "showmap `pidof com.android.systemui`" > showmap.txt
adb shell "dumpsys meminfo com.android.systemui" > meminfo.txt
adb pull /data/local/tmp/filemap.perf.data
  1. 执行如下脚本导出下文件 inode 信息,filemap_catch 在网盘中下载
adb push filemap_catch /data/local/tmp/
adb shell
su # 需 root 手机
cd /data/local/tmp/
./filemap_catch -d

最终生成文件列表

filemap.perf.data
showmap.txt
meminfo.txt
filemap_inode.json

非自启应用

以 com.miui.gallery 相册为例,需要手机有 root 权限

  1. 停止 APP 运行
adb shell am force-stop com.miui.gallery
adb shell "kill -9 `pidof com.miui.gallery`"  # 或者直接杀掉
  1. 执行 drop cache
adb shell "echo 3 > /proc/sys/vm/drop_caches"
  1. 执行 simpleperf 抓取命令后(执行 filemap 申请命令即可),同时执行步骤 4
# filemap 申请
# usap64 方式,丢失率高,但采样多
adb shell "chrt -f 10 simpleperf record -g -p `pidof usap64 | tr ' ' ','` --duration 10 -e filemap:mm_filemap_add_to_page_cache -c 1 -m 65536 --cpu-percent 99 --user-buffer-size 1536M -o /data/local/tmp/filemap.perf.data"
# --app 形式,丢失率低,但采样少
adb shell "chrt -f 10 simpleperf record -g --app com.miui.gallery --duration 10 -e filemap:mm_filemap_add_to_page_cache -c 1 -m 65536 --cpu-percent 99 --user-buffer-size 1536M -o /data/local/tmp/filemap.perf.data"
# filemap 释放
adb shell "chrt -f 10 simpleperf record -g -p `pidof usap64 | tr ' ' ','` --duration 10 -e filemap:mm_filemap_delete_from_page_cache -c 1 -m 65536 --cpu-percent 99 --user-buffer-size 1536M -o /data/local/tmp/filemap.perf.data"
  1. 启动 APP
adb shell "monkey -p com.miui.gallery -c android.intent.category.LAUNCHER 1"
  1. 等待 simpleperf 抓取完成后抓取 showmap 和 meminfo 并导出数据
adb shell "showmap `pidof com.miui.gallery`" > showmap.txt
adb shell "dumpsys meminfo com.miui.gallery" > meminfo.txt
adb pull /data/local/tmp/filemap.perf.data
  1. 执行如下脚本导出下文件 inode 信息
adb push filemap_catch /data/local/tmp/
adb shell
su # 需 root 手机
cd /data/local/tmp/
./filemap_catch -d

最终生成文件列表

filemap.perf.data
showmap.txt
meminfo.txt
filemap_inode.json