Perfetto heapprofd 完全指南:如何从火焰图到 SQL 查清堆内存的每一分去向

发布时间:2026/9/24 15:56:31

Perfetto heapprofd 完全指南:如何从火焰图到 SQL 查清堆内存的每一分去向 Perfetto heapprofd 完全指南如何从火焰图到 SQL 查清堆内存的每一分去向【免费下载链接】perfettoProduction-grade client-side tracing, profiling, and analysis for complex software systems.项目地址: https://gitcode.com/GitHub_Trending/pe/perfettoPerfetto heapprofd 是一个把进程里每一次堆内存分配与释放都归因到具体 callstack 的采样式分析器默认盯住malloc/free与 C 的new/delete。如果你正在排查内存越用越多、RSS 一路飙的问题它能直接回答谁、在哪条调用栈上、分了多少字节还没还回去——这是 OOM 排查里最难拿到的一手证据。下文按先上手、后原理、再深挖的顺序带你走完从一行命令到 SQL 查询的完整链路。从一个具体场景开始内存翻倍了是谁在分配场景一个工具类 App 跑两天dumpsys meminfo里 Native Heap 的 Private Dirty 从 50 MB 涨到 110 MB杀掉进程重启后又回落。重启即恢复说明不是碎片化而是有代码在持续借了不还。此时 RSS 曲线只能告诉你涨了答不了谁涨的。heapprofd 的做法是在目标进程内 hook 分配器把分配事件连同当时完整的调用栈一起记下事后按 callstack 聚合出哪条路径的分配没有配对释放。它的边界也要清楚只覆盖走默认 C/C 分配器的内存组件直接mmap拿的内存不在它的视野内。3 分钟上手heap_profile 一行命令跑通第一条火焰图结论先行优先用仓库自带的 tools/heap_profile 脚本它把配置生成、adb 交互、结果落盘都封装好了。设备用 adb 连上后按包名发起分析tools/heap_profile android -n com.example.myapp看到 Profiling active 就去操作 App复现你要排查的行为按 Ctrl-C 结束。脚本会打印输出目录形如/tmp/heap_profile-XXXXXX并附带heap_profile-latest软链把里面的raw-trace上传到 Perfetto UI时间线上会出现堆转储 slice点进去就是火焰图。TIP分析 App 时把libart.so加进 Hide Frame 过滤器火焰图会聚焦业务代码顶部 Filters 框还能按函数名聚焦比如输入applyStyle只看含该帧的调用栈。按 PID 分析把-n换成-p pid加--print-config可以只打印生成的配置不实际执行方便自查。全部参数见 heap_profile 命令行参考。采样原理hook malloc/free按 4096 字节做抽检这节回答默认配置为什么几乎无感代价又是什么。heapprofd 在目标进程里 hook 住malloc/free和operator new/delete给定采样间隔 n平均每分配 n 字节才记录一次默认 n 4096 字节对应 CLI 的-i/--interval。直观的理解把进程的全部分配行为看作一条 1 字节的流水每个字节被抽中的概率是 1/n一旦命中对应 callstack 记上完整的 n 字节。两条修正规则保证估算不失真大于采样间隔的分配绕过抽检直接按真实大小入账大对象不会被低估把sampling_interval_bytes设为1即全量采样精度完美开销也最大。另外还有自适应采样共享内存缓冲剩余空间低于adaptive_sampling_shmem_threshold时采样间隔自动翻倍直到adaptive_sampling_max_sampling_interval_bytes封顶两者置 0 即关闭。更完整的推导见 heapprofd 采样设计文档。三种启动方式怎么选脚本、手动 proto 与 UI 录制页结论绝大多数场景用脚本就够了只有堆分析要和 CPU、调度、日志等数据源在同一条 trace 里并行采集时才值得手写配置。方式适用场景代价tools/heap_profile推荐快速定位单个 App/服务Android 与 Linux 主机通用单条 trace 只采堆数据手写HeapprofdConfig堆分析 任意其他数据源同 trace 并行自己写并调试 protoPerfetto UI 录制页#!/record/memory浏览器零配置实验Windows 上也可用同样只能单数据源手动方式的最小 proto数据源名必须固定为android.heapprofddata_sources { config { name: android.heapprofd heapprofd_config { sampling_interval_bytes: 4096 process_cmdline: com.example.myapp } } }最常用的字段速览其余字段去 heapprofd_config.proto 查字段说明sampling_interval_bytes采样间隔字节。必须非零否则 producer 不启动设 1 全量process_cmdline按进程名匹配v57 支持*通配符仅匹配运行中进程需配no_startuppid按 PID 匹配heaps要采样的堆名如libc.malloc、com.android.art留空 只采 mallocAndroid 12continuous_dump_config周期转储dump_phase_ms首次转储延迟、dump_interval_ms转储间隔shmem_size_bytes客户端与 heapprofd 的共享内存缓冲默认8 MiB须 ≥8192、4096 的倍数且为 2 的幂block_client缓冲满时阻塞目标进程而非提前结束 trace会明显拖慢目标no_startup/no_running只匹配运行中进程 / 只匹配新启动进程二者互斥Android 11读懂数据火焰图四种视图、按需快照与连续转储 这节回答点进火焰图之后每个数字到底是什么意思。每次转储对每条 callstack 提供四种口径UI 的 Measure 选择器里可切换视图含义Unreleased malloc size区间内分配且未释放的字节数默认视图查泄漏首选Total malloc size区间内分配的总字节数含已配对释放的Unreleased malloc count没有配对释放的分配次数Total malloc count分配总次数含已释放的除了会话结束出单个总快照的默认行为你手里还有两个控制时间切片的开关按需快照adb shell killall -USR1 heapprofd可随时给所有在分析的进程拍一次快照适合自动化测试里在特定状态下留一张证据。它叠加在结束快照之上可以触发多次输出目录里按序枚举。连续转储命令里加-c 5000等价于 proto 中continuous_dump_config { dump_interval_ms: 5000 }UI 里就会每 5 秒出现一个 slice可拖选多个连续 slice 汇总一个时间窗。SQL 深挖分配数据落在哪几张表怎么查累积分配这节回答分配数据到底落在哪几张表。callstack 信息由三张表描述——stack_profile_mapping库/binary 名与 build_id、stack_profile_frame函数名与rel_pc、stack_profile_callsite调用点靠parent_id串成调用树离线符号化结果存stack_profile_symbol。分配事件本身在heap_profile_allocation视图里它是 intrinsic 表__intrinsic_heap_profile_allocation的封装count/size为正表示分配为负表示释放二者求和即 Unreleased 口径。第一段查询把分配明细按帧 join 出来select a.callsite_id, a.ts, a.upid, f.name, f.rel_pc, m.build_id, m.name as mapping_name, sum(a.size) as space_size, sum(a.count) as space_count from heap_profile_allocation a join stack_profile_callsite c on (a.callsite_id c.id) join stack_profile_frame f on (c.frame_id f.id) join stack_profile_mapping m on (f.mapping m.id) group by 1, 2, 3, 4, 5, 6, 7 order by space_size desc;跑完你会发现结果里几乎全是malloc/realloc——叶子帧信息量太低。真正想要的是某个函数出现在调用栈任意位置时累计分了多少而递归追parent_id用纯 SQL 很难写。标准库替你做完了这件事模块实现见 summary_tree.sqlINCLUDE PERFETTO MODULE android.memory.heap_profile.summary_tree; SELECT name, mapping_name AS map_name, cumulative_size FROM android_heap_profile_summary_tree order by abs(cumulative_size) desc;cumulative_size即该函数出现在调用栈任意位置时分配且未释放的字节数按绝对值降序排头部几行就是你要找的谁分掉了这 392 KB。同目录下的callstacks.sql、intervals.sql还提供调用栈展开与时间窗聚合能力。进阶话题启动分析、并发会话互斥与 ART Java 分配这节收三个容易踩坑、又常被忽略的行为语义。启动分析 vs 运行时分析按名字指定目标时会话启动后新拉起且匹配的进程会从启动即被分析trace proto 里对应ProcessHeapSamples.from_startup true而对已运行进程发请求则不同——hook 要等到下一次分配发生几百毫秒后才真正生效目标若正空闲随后的一波分配突发可能被漏掉。Android 上 Java App 不是 exec 出来的而是从 zygote fork 后特化成具体 App启动分析从特化点接管特化最早一小段分配不计入。并发会话互斥多个会话盯同一个目标时只有第一个会话采得到数据其余会话的ProcessHeapSamples为空且rejected_concurrent true转 pprof 时会报进程已被分析过。见到这个提示先adb shell killall perfetto清掉残留会话。ART Java 分配Android 12给脚本加--heaps com.android.art等价于 proto 里heaps: com.android.art即可改采 Java 堆。注意Java 分配分析要求 Android 12且别和 Java 堆转储heap dump搞混——前者是时间轴上累积的分配 callstack后者是存活对象快照的保留关系。ART 样本只记录对象创建时的栈不跟踪释放与 GC 回收提供 Total allocation size / Total allocation count 两个视图适合看内存 churn哪类代码在疯狂造对象又快速扔掉。另外Java 方法名带[DEDUPED]表示多个方法共享同一份代码ART 元数据只存了其中一个方法名——显示出来的未必是实际被调用的那个。资格与版本坑先确认你的进程有资格被分析空 profile 的第一嫌疑永远是资格问题。目标能否被分析取决于 Android 构建类型目标类型userdebug (setenforce 0)userdebuguser关键原生服务YNN普通原生服务YYN普通 AppYYNprofileable AppYYYdebuggable AppYYYuser 构建上对无资格进程发请求只会得到空 profileuserdebug 上被禁的是 sepolicy 中never_profile_heap圈定的一小撮关键服务可用adb shell su root setenforce 0或给脚本传--disable-selinux解除。想让自家 App 在 user 构建上可被分析在 manifest 的application段加profileable android:shelltrue/。注意proto 里的all: true分析全部合格进程在未改动的 userdebug 构建上会导致系统崩溃——zygote 拉新进程时撞上意外的 heapprofd socket 直接挂掉慎用。已知问题合并成一张版本矩阵✓ 该版本存在此问题问题A10A11A12A1364 位设备无法分析 32 位程序✓✓x86/x86_64 平台不支持含 Cuttlefish 模拟器✓sampling_interval_bytes设为 0 会崩溃目标进程✓✓启动分析部分帧名缺失A12 起修复✓✓Java 帧 unwinding 失败栈顶只剩单个 unknownA13 QPR1 修复✓✓子进程 vfork/clone(CLONE_VM) 内分配导致 profile 提前结束Runtime.exec会触发可--disable-fork-teardown缓解✓dump_at_max的对象计数可能不准✓✓shmem 过小 block_client可能卡死目标✓✓每次结束 logcat 出现Failed to send control socket byte.良性✓✓带 load bias 的库函数名不准离线符号化可解✓ARM32 最底层帧恒为ERROR 2无害栈仍完整✓root shell 裸跑 heapprofd 使 socket 拿到错误 SELinux 域restorecon /dev/socket/heapprofd修复✓数字为什么对不上heapprofd、malloc_info 与 RSS 的口径这节回答为什么三个工具报出来的内存各说各话。它们量的是不同层面指标计量的是什么拿法量级关系heapprofd目标向默认 C/C 分配器请求的字节不含 zygote 特化前的分配Java App、线程缓存与碎片tools/heap_profile最小malloc_info分配器视角含线程缓存中已 free 未归还的内存覆盖 zygote 前分配userdebug 上am dumpheap -m PID /data/local/tmp/heap.txt居中Heap RSS分配器向操作系统要到的内存按页取整 碎片浪费进程被换出到 ZRAM 时反而可能变小adb shell dumpsys meminfo PID看 Private Dirty 列通常最大判断口诀RSS 或 malloc_info 明显高于 heapprofd而调用栈上又找不到漏大概率是分配器里某种病态碎片化——此时该去审视分配器本身而不是继续追调用栈。离开 Android在 Linux 主机上分析本地进程 这节讲不连设备怎么分析。从 v58 起heap_profile host子命令支持直接分析本机 Linux 进程tools/heap_profile host -- ./my_binary --some-flag脚本内部走四步首次运行自动下载tracebox与libheapprofd_glibc_preload.solinux-amd64 / arm / arm64到~/.local/share/perfetto/prebuilts/通过tracebox --system-sockets拉起内置traced守护进程以LD_PRELOAD指向 preload 库启动目标并置PERFETTO_HEAPPROFD_BLOCKING_INIT1——默认 heapprofd 懒初始化、不阻塞主线程会漏掉启动期分配设了该变量后第一次malloc会阻塞到 hook 完全挂好保证每笔分配都被记到等目标退出或你按 Ctrl-C运行trace_processor产出 gzip 压缩的 pprof 与原始 trace并打印输出目录。不传-n时进程名默认取--后二进制的 basename。预编译包没有你的平台时可从源码构建 preload 库再用--preload-library传入。注意host子命令只在 Linux 上可用其他平台会直接报错退出。排错四件套缓冲溢出、空 profile、怪调用栈与符号化失败按出现频率从高到低过一遍。缓冲溢出profile 提前结束分配速率压垮了 heapprofd。若是短暂尖峰把--shmem-size调大须为 4096 的倍数、≥8192、2 的幂脚本会严格校验若是持续高水位用--interval16000或更大值牺牲精度换存活。空 profile先按上一节资格矩阵核对目标是否有资格再翻版本坑矩阵两者都排除后确认进程真的被匹配到了名字归一化规则含/取最后一段、含截断。看起来不可能的调用栈先查栈里有没有[DEDUPED]帧其次若链接时开了 ICF-Wl,--icf...平凡函数常见如构造/析构函数可能被别名到毫不相干类的二进制等价体上栈会合理但离谱。符号化失败could not find library、Build ID 对不上、栈里只剩一帧都指向离线符号化流程完整工作流含传统PERFETTO_BINARY_PATH/PERFETTO_PROGUARD_MAP与trace_processor bundle增强归档见 符号化文档。收尾转 pprof 与该不该用 heapprofd选型小结这节收两个东西pprof 转换命令和一张选型判断卡。tools/trace_processor convert profile /tmp/profile gzip /tmp/heap_profile-XXXXXX/*.pb得到 gzip 压缩的 pprof profile proto即可交给各类 pprof 消费工具。选型小结3 秒判断你的场景想知道谁在分配、哪条调用栈没还内存native 为主→ heapprofd想量化Java 对象造得多快、churn在哪Android 12→ heapprofd --heaps com.android.art想回答此刻哪些存活对象被谁引用着泄漏的持有链→ ART heap dump流程见 Android 内存排查案例怀疑内存走的是裸mmap驱动、自定义分配器→ 换 ftrace/perf 抓 mmap 系统调用heapprofd 看不见这部分只想看 RSS 趋势与 OOM 时间线 →dumpsys meminfo 内存计数器数据源即可不必上采样。数据源全貌与更多实战见 native-heap-profiler 官方文档。【免费下载链接】perfettoProduction-grade client-side tracing, profiling, and analysis for complex software systems.项目地址: https://gitcode.com/GitHub_Trending/pe/perfetto创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/24 15:56:31

基于vue的蛋糕定制预约自提系统[Vue]-计算机毕业设计源码+LW文档

摘要‌:随着消费者对个性化蛋糕需求的增长以及线上消费习惯的普及,开发一个高效便捷的蛋糕定制预约自提系统具有重要的现实意义。本文阐述了一个基于Vue框架开发的此类系统,详细介绍了其从需求分析到设计、实现的全过程。系统实现了用户蛋糕定…

2026/9/24 17:06:39

Windows 跑 Codex:原生 PowerShell 还是 WSL2?仓库放错最容易踩坑

Windows 跑 Codex:原生 PowerShell 还是 WSL2?仓库放错最容易踩坑 [!NOTE] Windows 版 ChatGPT 桌面应用默认使用 Windows 原生 Codex Agent,并在 PowerShell 环境运行;也可以把 Agent 切换到 WSL2。 “Agent 在哪里运行”“集成终端显示什么”“仓库实际存在哪个文件系统”…

2026/9/24 17:06:39

一个项目挂 3 个仓库:Codex 多文件夹项目与跨仓 Diff 怎么审

一个项目挂 3 个仓库:Codex 多文件夹项目与跨仓 Diff 怎么审 [!NOTE] ChatGPT 桌面应用的本地 Project 可以附加多个文件夹,并指定一个 Primary folder;Codex 能读写所有附加目录,但自动发现 AGENTS.md、Skills、config.toml 和默认 Git 操作仍以主目录为中心。 Review pan…

2026/9/23 12:07:00

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/23 12:06:55

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/24 0:00:21

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为…

2026/9/24 0:00:21

单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

简介:一份基于单细胞RNA测序数据的细胞类型注释算法研究Python毕业设计源码,针对计算机相关专业正在做毕设或需要项目实战的学习者,可用于课程设计与期末大作业。项目代码完整、经导师指导评审通过,可直接运行,覆盖数据…

2026/9/24 0:00:21

C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

第一次在项目里被反射卡住,是在一个老旧的WinForms模块里:几十个类依赖PropertyChanged通知,运行时反射读属性、发通知,每次启动慢半拍不说,一上.NET Native/AOT裁剪模式几乎全面崩盘。后来我把这段逻辑全部改成C#源生…

2026/9/22 16:34:32

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/22 20:01:30

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/22 13:25:41

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码