【Android内存】Native内存占用分析

2,883 阅读3分钟

一、背景

内存对于应用来说是非常重要的性能指标,直接影响了应用在后台的存活时间以及性能表现。Linux内核有个这样的机制:它会监控每个进程的内存使用情况,并使用oom_score_adj来对进程的内存使用情况进行评分。一个进程的内存占用的使用越多,也会间接带来流程性问题(系统低内存查杀的影响),在后台被系统机制查杀的概率也越大。

我们在分析应用的内存时,通常会直接通过adb 命令dump meminfo来获取当前内存的基本情况: image.png

有时候我们发现Native Heap在做完需求后变大了,并想分析下这块变大的原因,通常我们可以通过抓取hprof文件来获得java对象的分配情况,从而间接知道natvie内存增长的原因。
一般来说,对于普通的应用来说,native内存的增长情况主要来自于bitmap对象、线程创建、so库的调用等。
如果我们想进一步知道分配的细节,想调试下这口内存的分配情况,我们还可以通过以下方法来进行。

二、分析方法

native内存的分析方法,对于我们应用开发来说,接触较多的可能就是malloc debug。通过adb 命令直接触发native内存的debug,但有个明显的缺点:需要用到root版本的手机。
这里将介绍另外一种方式:基于perfetto工具的native内存调试方法,条件上要求比malloc debug会方便些,操作的步骤也比较简单,我们一起看下。

image.png

三、分析过程

2.1 条件

a)当前的安卓系统需要是Q及以上的版本; b)被调试的应用需要时debug版本。当然如果当前系统时root版本,你甚至可以调试系统应用的native内存分配情况。

2.2 脚本下载

你需要到以下地址下载要执行的脚本: raw.githubusercontent.com/google/perf…

并将该脚本保存成.py格式的文件,如heap_profile.py

2.3 执行命令

heap_profile.py -n com.nativeheap.demo -d 5000 -o <out put file path>

其中,对应的参数含义如下:

 -d:日志抓取的时长:
 -n:抓取的目标应用;
 -o:结果输出的目录(执行前要为空文件)

2.4 结果解析

1) 执行完以上命令后,我们将在结果文件夹中看到一下trace文件:
image.png
2)这时候我们可以将结果文件拖到perfetto( ui.perfetto.dev/ )中进行解析并查看:

image.png

2.5 结果解读:

1)标签定义

image.png
这里面有几项,包括space、alloc space、objects、alloc objects,这里我们只需要关心space即可,即未被释放的nativeheap。

2)内存分配概览

数据解析出来后,我们可以看到分配的情况如下: image.png image.png

3)关键字搜索

在解析出的结果中,搜索对应的关键字: image.png

4)SQL查询

perfetto另个一强大之处就是支持SQL的查询,如: image.png image.png 详细的使用介绍可以参考: perfetto.dev/docs/data-s…

5)相关代码

分析的基本原理是在内存分配和回收的接口处注入了自定义的指令,以统计内存的分配和释放情况,perfetto相关的源码地址如下:android.googlesource.com/platform/ex…

三、参考链接

perfetto.dev/docs/data-s…

perfetto.dev/docs/case-s…