当前位置: 首页 > news >正文

APP 内存测试--Android Memory Profiler实操(入门版)

背景: 内存作为程序运行的核心资源,合理分配与回收至关重要。不合理的内存管理不仅会导致应用卡顿、ANR或黑屏等问题,严重时甚至引发OOM(内存溢出)崩溃,严重影响用户体验。APP内存测试我们一般关注内存抖动和内存泄漏方面的问题

一、APP内存测试

1.1 内存抖动

        内存抖动的产生原因是短时间内有大量的内存申请和释放,造成了内存抖动厉害。内存抖动最直接的影响是可能会造成app使用过程中的卡顿,因为内存抖动伴随着大量的GC,现在的机制GC是会造成短暂的停顿。

1.2 内存泄露

        Android系统为每个运行程序设定了内存上限,一旦超出限制便会触发OOM(内存溢出)机制。这通常表现为应用闪退或崩溃。常见诱因包括内存泄漏,以及无节制地占用大量系统资源等不当编程行为。

     Android内存在分配之后,由于被生命周期比它长的对象引用造成在使用完之后也无法释放。

1.3 Android Profiler介绍

        Android Profiler的Memory Profiler组件, 可用于帮助我们分析内存泄露和内存抖动的问题。Memory Profiler的功能包括:  展示应用内存使用情况的实时图像、抓取内存的dump信息、强制垃圾回收及追踪内存分配。

二、环境准备

 2.1  将手机通过USB链接至电脑,连接时需要确认手机是处于“USB调试”模式
 2.2   打开AndroidStudio,从底部的控制台选择Android Profiler

如果底部没有Android Profiler选项,可以从顶部工具栏 View—Tool Windows—Profiler

3、在Android Profiler中,点击SESSIONS后方的“+”,然后选择已连接的设备及自己要测试的APP的进程名,如【com.xxxx.xxx】。

4、点击后如下图,我们可以看到Android Profiler分为四大模块: CPU、内存 、网络、能耗:

5、单击MEMORY时间轴中的任意位置打开MEMORY Profiler,如下图所示;点击旁边箭头可返回上一级页面

三、通用测试步骤

      1. 进入某一个页面,滑动页面,多滑几次,然后退出页面,进行GC。
      2.进入某一页面,操作一些界面元素,比如加载更多元素、删除某个元素、增加某个元素等。
      3. 进入某一个页面,接收和处理大量网络数据的场景,比如下载大量的图片等。
      4.对于新增模块,比较和上个版本的内存值,内存增加是否符合预期。
      5.APP启动过程中(热启动、冷启动、首次启动),内存的变化情况。

Memory Profiler界面按钮说明: 如下图

标注①按键:用于强制内存回收。

标注②按键:用于抓取进程内存的dump信息。

标注③按键:用于记录内存的分配信息。  初次点击Record native allocations时,对应统计的开始时间点;再次点击时,对应统计的结束时间点。进程在两个时间点之间的内存分配信息,将被Memory Profiler记录和分析。

标注④区域:用于缩放/复原时间轴。

标注⑤按键:用于显示/停止显示实时的内存数据。

标注⑥区域:用于记录事件发生的时间点及大致持续的时间(例如点击事件、返回事件、屏幕旋转事件等事件)。

Memory Profiler统计内存种类及其含义

Total:表示app独自占用内存,后面几项之和;

Java:表示Java代码或Kotlin代码分配的内存;

Native:表示C或C++代码分配的内存(即使App没有native层,调用framework代码时,也有可能触发分配native内存);

Graphics:表示图像相关缓存队列占用的内存;

Stack:表示native和java占用的栈内存;

Code:表示代码、资源文件、库文件等占用的内存;

Others:表示无法明确分类的内存;

Allocated:表示Java或Kotlin分配对象的数量。

四、基本用法

4.1 查看内存分配情况

Memory Profiler可以查看两个时间点之间的内存分配情况

4.1.1  点击内存统计任意区域,会显示两条线,拖拽任意一条线,即可以选择观察区域;

4.1.2  选定观察区域后, 下方Table区域就可以统计这段时间内分配对象的类名;

4.1.3  因为类比较多,我们可以在搜索框,输入关键字(比如:cert),找到我们想要关注的类(可以与开发沟通)后,点击该类,然后会在右侧Instance View显示具体的对象; 

4.1.4  点击具体对象后,会在Allocation Call Stack区域显示调用栈。点击调用栈信息后,就会跳转到具体的代码(前提是你本地有代码)。

Allocations :表示实例数量

Shallow Size:表示对象使用Java内存的大小,单位为byte; 

4.2 查看内存占用情况

4.2.1 在Memory Profiler界面点击Dump Java heap按钮,抓取点击后一段时间内app占用内存的dump信息(文件可能会比较大),生成堆转储文件 hprof。

4.2.2  抓取后会自动解析hprof文件信息,并且统计出Classes、Leaks、Count、Native Size、Shallow Size、Retained Size数量;

        同样我们也可以通过搜索框输入关键字,搜索我们想要关注的类(如:cert),这里我们可以看到有一处泄漏的地方;

4.2.3 点击类后,会在下方Instance显示具体的对象;

4.2.4 点击具体的对象后,会在右侧显示详细信息;

Depth:表示当前对象到任一GC root的最短跳数;

Native Size:表示类对象所引用的Native对象所消耗的内存的大小;

Shallow Size:表示对象使用Java内存的大小,单位为byte; 

Retained Size:表示对象占用的实际内存大小,大于等于Shallow Size;

五、测试结果分析

 5.1 内存抖动

        如果在很短的时间内发生了多次的内存申请和释放,有多处高峰值,虽然也有回收操作,但是尖峰值过多,垃圾回收站频繁操作,导致短时间内执行了多次GC操作。出现这种现象的时候,明显能感觉到App的卡顿,甚至出现应用进程被干掉,这种现象则可判断为此操作中存在内存抖动现象。

5.2 内存泄漏

        内存泄露时 Memory Profiler 会呈现一个类似阶梯型的内存上升趋势

六、测试标准

 6.1 内存抖动
          10s内出现 大于等于 4次的内存波动(图形上有4个毛刺),如下图即为不通过。

 6.2  内存泄露
        理论上不能有任何的内存泄露。

七、dumpsys meminfo

    命令行方式查看内存情况

   查看设备内存使用情况:adb shell cat /proc/meminfo

7.1  App运行内存

我们目前主要关注两方面的运行内存:app启动内存平均值、app运行主要功能之后的内存平均值

查看某APP应用内存使用信息:adb shell dumpsys meminfo com.xxxx.xxx(待测应用包名)

属性说明1:

Uptime:表示启动到现在的时长,不包含休眠的时间,单位毫秒(ms)

Native Heap:由C/C++申请的内存空间在native heap

Dalvik Heap:由java对象申请的对象,全部都在Dalvik Heap,我们通常关注一个app的内存是Dalvik Heap。

Dalvik Other:类数据结构和索引占据的内存

Stack:栈内存

Unknown:无法归类到上面提到的内存类型中,除此之外的内存。

TOTAL:各个项占用的内存的总值。

Pss total(Proportional set Size 按比例分配占用内存):实际使用内存

Private Dirty & Clean:指的是进程独占内存。通常我们更关注Private dirty内存,因为这部分内存是在应用退出之后,可以被回收的内存。换句话说,这部分内存是应用 new 出来的对象实例。

 SwapPss Dirty:用于监视系统中内存交换操作的情况

Heap size:虚拟机Heap 的大小,指占用总内存(Heap  堆)

Heap Alloc : 统计的是虚拟机分配的所有应用实的内存大小

Heap Free: 虚拟机当前可用的Heap大小(空闲内存)。

属性说明2:

说明:

Graphics:为图形的内存使用情况

Total PSS:上下两部分其实是对此应用使用内存量做了不同分类,值是相同的,都是75685

Objects:表示该app的一些对象的数量,例如view控件存在44个,Activity分配的内存有1个

SQL & DATABASES:是app操作过程中数据库相关的内存情况

Asset Allocations : 这里是将asset下面文件解压之后,放到内存中。

7.2  结果分析

 7.2.1 建议App占用内存采用 Pss Total 的值。(因为这个是app 进程真实占用的内存值)。  

  至于Heap Size、Heap Alloc、Heap Free是Dalvik所分配的堆大小(反映了java代码分配的内存,但是也会包含Zygote共享的内存)

7.2.2 建议采集3到5次的内存数据,求平均值。

7.2.3  对前后两个版本的内存(或者三个版本)进行数据对比。

八、 其他说明

Android系统对dalvik的vm heapsize作了硬性限制,当java进程申请的java空间超过阈值时,就会抛出OOM异常(这个阈值视机型而定)

  查看单个应用最大内存限制,我们可以在shell中输入命令:getprop|grep heapgrowthlimit 

可以看到我的测试机(荣耀Magic3)的限制为384M,dalvik process 超过就会抛OOM(out of memory)异常

http://www.dtcms.com/a/263450.html

相关文章:

  • ACE之ACE_NonBlocking_Connect_Handler问题分析
  • 【FineDataLink快速入门】01界面介绍-运维中心
  • AI教育全景图:谁在领跑2025?
  • 【Debian】1- 安装Debian到物理主机
  • STM32——DAP下载程序和程序调试
  • 【C++】经典string类问题
  • 【数字人开发】结合nextHuman平台进行数字人网页端开发
  • VMware 在局域网环境将虚拟机内部ip 端口开放
  • 【读代码】TradingAgents:基于多智能体LLM的金融交易框架深度解析
  • STM32 rs485实现中断DMA模式收发不定长数据
  • STM32-第一节-新建工程,GPIO输出(LED,蜂鸣器)
  • SQuirreL SQL:一个免费的通用数据库开发工具
  • 华为云Flexus+DeepSeek征文 | 基于华为云Dify-LLM搭建知识库问答助手
  • 怎么在手机上预约心理咨询师
  • MySQL索引失效场景
  • 【软考高项论文】信息系统项目的资源管理
  • 大模型在急性左心衰竭预测与临床方案制定中的应用研究
  • 【Redis面试篇】Redis高频八股汇总
  • 长短期记忆网络(LSTM):让神经网络拥有 “持久记忆力” 的神奇魔法
  • 周赛98补题
  • Go语言安装使用教程
  • Golang的多环境配置
  • 「Java流程控制」while循环
  • Redis 实现消息队列
  • 【软考高项论文】论信息系统项目的质量管理
  • js代码01
  • 【数据分析】环境数据降维与聚类分析教程:从PCA到可视化
  • uniapp+vue2 input不显示明文密码,点击小眼睛显示或隐藏密码
  • “对象创建”模式之原型模式
  • window显示驱动开发—全屏模式