安卓性能优化之内存优化

news2024/11/15 13:22:25

Java对象生命周期:

  1. 创建:为对象分配内存空间,构造对象
  2. 应用:此时 对象至少被一个强引用持有
  3. 不可见:未被任何强引用持有,进行可达性分析
  4. 不可达:可达性分析为不可达,进入下一阶段
  5. 收集:当垃圾回收器发现该对象已经处于“不可达阶段”并且垃圾回收器已经对该对象的内存空间重新分配做好准备时,则对象进入了“收集阶段”。如果该对象已经重写了finalize()方法,则会去执行该方法的终端操作。
  6. 终结:当对象执行完finalize()方法后仍然处于不可达状态时(可达性分析垃圾回收算法被回收前,会有两次标记过程,判断是否执行l finalize()方法,执行完之后判断是否GC ROOT可达,如果仍不可达,则准备回收),则该对象进入终结阶段。在该阶段是等待垃圾回收器对该对象空间进行回收。
  7. 对象空间进行重新分配

对象的内存布局:

请添加图片描述

Android内存回收机制:

  1. 对象创建后在Eden区
  2. 执行GC后,如果对象仍然存活,则复制到S0区
  3. 当S0区满时,该区域存活对象将复制到S1区,然后S0区清空,接下来S0和S1角色互换.
  4. 当第3步达到一定次数(系统版本不同会有差异)后,存活对象将对复制到Old Generation
  5. 当这个对象在Old Greneration停留的时间达到一定程度时,它会被移动到Old Generation,最后积累一定时间再移动到Permanent Generation区域

年轻代使用mimor GC速度快,老年代使用full GC速度就会慢很多。

Dalvik虚拟机内存分配:

  • Linear Alloc:匿名共享内存
  • Zygote Space:Zygote相关的一些信息
  • Alloc Space:每个进程 独占

ART:

Non Moving Space

Zygote Space

Alloc Space

Image Space:预加载的类信息

Large Obj Space:分配大对象 如bitmap

可达性分析算法GCoot:

请添加图片描述

Java的四种引用:

  • 强引用

  • 软引用:GC扫描到不一定被回收,只有内存不足时才会被回收

  • 弱引用:被GC扫描到就会被回收

  • 虚引用:没有引用

垃圾回收算法:

标记清除法:

特点:

位置不连续,产生碎片,效率略低,两次扫描

多次扫描后会产生大量内存碎片

复制算法:

特点:

实现简单,运行高效,没有内存碎片,利用率只有一半

假设内存又4M,使用的只有2M

标记整理算法:

特点:

没有内存碎片,效率偏低,两遍扫描,指针需要调整

扫描标记可回收后,整理存活对象和可回收对象,分区

分代收集算法:

综合运用

新生区对象存活低使用复制算法,老年区对象存活久,清除频率低,使用标记算法

App内存组成以及限制

Android给每个app分配一个VM,让app运行在dalvik上,这样即使app崩溃也不会影响到系统。系统给VM分配了一定的内存大小,app可以申请使用的内存大小不能超过此硬件逻辑限制,就算物理内存富余,如果应用超过VM最大内存,就会出现内存溢出crash。
由程序控制操作的内存空间在heap上,分java heapsize 和native heapsize。

  • java申请的内存在vm heap上,所以如果java申请的内存大小超过vm的逻辑内存限制,就会出现内存溢出的异常。
  • native层内存申请不受其限制,native层受native process对内存大小的限制。

查看App内存限制

adb shell

cat /system/build.prop

通过代码获取

ActivityManager activityManager = (ActivityManager)getBaseContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
activityManager.getMemoryClass();

ams为什么能获取:因为 ams.setsystemprocess中的meminfobinder调用底层内存信息

app:内存 大小 每个厂商机型给初始分配内存不同 源码中有两个地方可以修改

1./frameworks/base/core/jni/AndroidRuntime.cpp

    parseRuntimeOption("dalvik.vm.heapstartsize", heapstartsizeOptsBuf, "-Xms", "4m");
    parseRuntimeOption("dalvik.vm.heapsize", heapsizeOptsBuf, "-Xmx", "16m"); //修改这里
  1. 安卓10以下/system/core/init/init.cpp

OOM解决问题 :主动获取了解当前app的内存使用情况

低内存杀进程机制

请添加图片描述

OOM Killer

oom_adj

app运行时,点击home app挂到后台 不会立马被系统杀掉,开多应用挂后台,安卓系统给应用分级

请添加图片描述

数字越大越容易被系统杀掉,粗粒度

app: 前台可见 oom_adj 0,后台2

oom_score_adj [-1000,1000] 更细粒度杀进程

adb shell下使用 cat /proc/进程号/oom_adj即可查询该应用的oom_adj值

若两个应用a 和b oom_adj值都是11 则谁占用内存多杀谁

所以要尽量降低应用进入后台的内存

内存三大问题

1.内存抖动

内存波动图呈锯齿状,GC导致卡顿

在AS中的Profiler中使用查看波动图,内存抖动会频繁GC,如自定义view中的ondraw()中频繁创建销毁画笔路径等,最后会导致内存千疮百孔

2.内存泄漏

在当前应用周期内不再使用的对象被GC Roots引用,导致不能回收,使实际可使用内存变小

产生泄漏之后不会立马导致应用崩溃,1个地方存在泄漏,程序跑久了之后,内存泄漏会一直积攒着,达到OOM级别,会导致应用低内存,会导致发热,耗电更严重的导致内存溢出

**注:**OOM不是只代表Java堆内存溢出。还因为无足够连续内存空间:FD(文件句柄,数字)数量超出限制;线程数量超出限制;虚拟内存不足;

3.内存溢出

即OOM,OOM时会导致程序异常。Android设备出厂后,Java虚拟机对单个应用的最大分配内存就确定下来了,超出这个值就会OOM

常见分析内存问题的命令

常用内存调优分析命令:

  1. dumpsys meminfo

内存指标概念:

Item全称含义等价
USSUnique Set Size物理内存进程独占的内存
PSSProportional Set Size物理内存PSS=USS+按比例包含共享库
RSSResident Set Size物理内存RSS=USS+包含共享库
VSSVirtual Set Size虚拟内存VSS=RSS+未分配实例物理内存

总结:VSS>=RSS>=PSS>=USS,但/dev/kgsl-3d0部分必须考虑VSS 看的时候主要看PSS

请添加图片描述

dumpsys meminfo --package + 包名可以查看具体应用的内存情况

  1. procrank
  2. cat /proc/meminfo
  3. free
  4. showmap
  5. vmstat
  6. top -n 1

总结:

  • dumpsys meminfo适用场景:查看进程的oom_adj,或者dalvik/native等区域内存情况,或者某个进程或apk的内存情况,功能非常强大
  • procrank:查看进程的VSS/RSS/PSS/USS各个内存指标
  • cat /proc/meminfo 查看系统的详尽内存信息,包含内核情况
  • free适用场景:只查看系统的可用内存
  • showmap 查看进程的虚拟地址控件的内存分配情况
  • vmstat 周期性地打印出进程运行队列,系统切换 ,CPU时间占比等情况

MAT性能分析工具:MemoryAnalyzer Tools

  • incoming references

被持有

  • outgoing references

持有

hprof-conv xxx.hprof 转一下即可用MAT打开内存快照

  • Shallow Heap 浅堆

单独自己的占用大小

  • Retained Heap 深堆

总计引用占用大小

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/181629.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

notes

等差:,求 解:、 ,则 解: x系数y系数1412 由 得分母 ;则分子为, 解:令 已知两边及夹角,可图解 解析几何条件转化 1.平行四边形条件的转化几何性质代数实现(1)对边平行斜…

【IoT】创业:如何找到可以主导的创业市场?

如果你想开始创业,开启一段不一样的旅程,那么你首先要做的就是选赛道! 如何选择你的赛道、你的第一个市场呢? 换句话说就是,你如何选择自己的利基市场。 最大的市场,同时,它的需求范围也最广…

全国地级市1999—2020年污染物排放和环境治理相关指标(废水\废气\粉尘等)

工业废水、工业粉尘等污染物是影响居住环境的重要因素,也是在各项研究中常用的数据!之前我们基于历年的《中国城市统计年鉴》整理了1999—2020年的人口相关数据和用地相关数据(可查看之前推送的文章)。在《中国城市统计年鉴》中也…

欧拉回路(模板+外加一些优化)

给定一张图,请你找出欧拉回路,即在图中找一个环使得每条边都在环上出现恰好一次。 输入格式 第一行包含一个整数t, t∈ {1,2},如果t 1,表示所给图为无向图,如果t2,表示所给图为有向图。 第二行包含两个整数…

【MySQL】日志

https://www.cnblogs.com/myseries/p/10728533.html 在 MySQL 中,有多种不同的日志,包括错误日志、二进制日志、查询日志和慢查询日志,这些日志发挥着不同的作用。另外还有redo日志、undo日志和relay日志。 错误日志 错误日志是 MySQL 中最…

测试篇(四):测试用例的分类、按测试对象划分、按是否查看代码划分、你平时哪种测试方法用的多?、按照开发阶段划分

目录一、按测试对象划分1.1 界面测试1.2 可靠性测试1.3 容测性测试1.4 文档测试1.5 兼容性测试1.6 易用性测试1.7 安装卸载测试1.8 安全测试1.9 性能测试1.10 内存泄露测试1.11 弱网测试二、按是否查看代码划分2.1 黑盒测试2.2 白盒测试2.4 灰盒测试三、面试题:你平…

AcWing 327. 玉米田(状态压缩DP)

AcWing 327. 玉米田(状态压缩DP)一、问题二、分析1、思路2、状态表示3、状态转移4、循环设计5、初末状态三、代码一、问题 二、分析 1、思路 这道题与之前所讲解的AcWing 1064. 小国王(状态压缩DP)非常相似,所以如果…

ARM uboot 的源码目录分析

一、uboot的源码目录分析1 1、九鼎官方 uboot 和三星原版 uboot 对比 (1) 以九鼎官方的 uboot 为蓝本来学习的,以三星官方的这份为对照。 (2) 不同版本的 uboot 或者同一版本不同人移植的 uboot,可能目录结构和文件内容都有所不同。将来大家懂了后也可…

剑指 Offer 第8天

目录 剑指 Offer 10- I. 斐波那契数列 剑指 Offer 10- II. 青蛙跳台阶问题 剑指 Offer 63. 股票的最大利润 剑指 Offer 10- I. 斐波那契数列 写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N)&#xf…

java并发编程面试题目及答案2(持续更新)

22、利用原子类手写 CAS 无锁 /** * 利用 cas 手写 锁 */ public class AtomicTryLock {private AtomicLong atomicLongnew AtomicLong(0);private Thread lockCurrentThread; /** * 1 表示锁已经被获取 0 表示锁没有获取 利用 cas 将 0 改为 1 成功则表示获取锁 * return */…

Linux find 命令

Linux find 命令用来在指定目录下查找文件。任何位于参数之前的字符串都将被视为欲查找的目录名。如果使用该命令时,不设置任何参数,则 find 命令将在当前目录下查找子目录与文件。并且将查找到的子目录和文件全部进行显示。语法find path -option [ -pr…

微服务-高并发-思路

一、为什么选择Go语言 Go 语言相对其它语言具有几点天然的优势: 语法简单,上手快性能高,编译快,开发效率也不低原生支持并发,协程模型是非常优秀的服务端模型,同时也适合网络调用部署方便,编译…

C语言深度解剖-关键字(3)

目录 1.关键字 sizeof C语言基本数据类型 认识 sizeof sizeof 相关扩展: 2. signed 与 unsigned 关键字 整形在内存的存储 如何快速转换二进制 写在最后: 1.关键字 sizeof C语言基本数据类型 以下是C语言基本的数据类型: 定义变量的…

Leetcode:37. 解数独(C++)

目录 问题描述: 实现代码与解析: 回溯: 原理思路: 问题描述: 编写一个程序,通过填充空格来解决数独问题。 数独的解法需 遵循如下规则: 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列…

分布式链路追踪SkyWalking进阶实战之RPC上报和WebHook通知(三)

目录 1.自定义SkyWalking链路追踪配置 1.1 什么是TraceId 1.2 使用的背景 1.3 编码 2.SkyWalking-RocketBot性能剖析 3.SkyWalking链路追踪-日志和RPC上报实战 4.源码部署 Apache SkyWalking 5.SkyWalking链路追踪-告警模块和WebHook通知《上》 6.SkyWalking链路追踪-…

对技术类的管理和绩效的一些想法

大家好: 我是烤鸭。看完春晚小品的心情(除了神马组合),就跟下面这哥们一样,尬的抠脚。再加上初一跟家人出去一趟,消费是真的复苏了,哪哪都排队。本来还想去洗温泉,给商家打电话一直占线…就能想象有多少人了…

7. 初步认识线程同步

前言:一旦接触到多线程编程,那么线程之间的同步就显得非常重要了。c/c#/java等高级语言都有自己的线程库,当然也提供了线程同步的API接口。打个比方,在C/QT中,线程的同步有以下几种方式:互斥锁、信号量、条…

2、SPSS的基本知识

目录 一、SPSS软件的安装和启动 二、SPSS的基本操作环境 (1)数据编辑窗口(主程序窗口) (2)SPSS结果输出窗口 三、SPSS软件的退出 四、SPSS软件的三种基本使用方式 五、SPSS数据的结构和定义方法 1.…

单链表——简单的增删查改

前言:上次介绍了顺序表,这次我要分享对单链表的一些简单理解,主要框架与上次大致相同,内容主要是单链表的增删查改,适用于初学者,之后会继续更新一些更深入的内容。同时,这也仅仅是我个人对所学…

不完全微分PID控制算法及仿真

在 PID控制中,微分信号的引入可改善系统的动态特性,但也易引进高频干扰,在误差扰动突变时尤其显出微分项的不足。若在控制算法中加入低通滤波器,则可使系统性能得到改善。克服上述缺点的方法之一是在 PID算法中加入一个一阶惯性环…