Android内存相关
预备知识
页:
我们把磁盘分很多块
,我们把这个块称为页(Memory paging)
,页
同时也是硬盘和内存最小的交换单位(一般为4k).
如果你想了解更多请参阅wikipedia: Memory paging(英文)
内存映射文件(Memory-mapped file)
假设我有一个exe程序
要运行,这个exe
大小为5g
,那么操作系统会将这个文件装载到内存(当然不会一次性装载完.).我们把这种操作称为内存映射文件(Memory-mapped file)
.
共享内存
操作系统很多资源是可用让多个程序共享的,比如动态库代码.在Android
的Zygote
在进行fork
出一个app
时,其内部包含很多共享的主题和资源等.在程序没有修改这些共享资源的时候,所有的程序的共享资源指向同一物理内存.
假设进程B修改动态库的内容,那么会将会拷贝动态库作为一个副本,然后在在副本里面修改.
Swap space
当内存不足时候linux操作会执行内存交换
的操作,大白话将就是一些不重要的程序的内存换出到硬盘,腾出的内存空间给新任务使用,而这块空间在linux我们把它称为交换空间(Swap space)
.等不重要的程序被重新调度时在将硬盘数据重新载入,但是成本极高. Android虽然是linux,但是在内存不足的时候并不会执行内存交换
操作,主要原因手机存储比较小,另外频繁的读取容易对多媒体存储硬件带来损失以及带来大量迁移操作会引起卡顿.
swap-space-linux-systems(英文)
VSS/RSS/PSS/USS
这四个是一个程序内存区域的一个术语
Vss = virtual set size
Rss = resident set size
Pss = proportional set size
Uss = unique set size
vss
:虚拟空间大小,操作系统会让程序认为自己可以掌握整个内存,所以虚拟一个完整内存空间给程序,表示整个程序内存,实际和物理内存需要做一次地址转化.(这里是操作系统基础知识不在这里铺开)
Rss
:程序实际占用的物理内存,包含共享内存的大小(比如加载动态就是一个共享内存),所以不方便查看实际自身所占用的内存
Uss
:不包含共享内存的程序大小
Pss
:两个内存区域大小的结合,第一个内存区域是自身非共享内存
的大小(Uss
),另一个共享内存所占的平均值,注意是平均值,这个平均值计算:假设共享内存为 4MB,然后这个共享内存被两个程序加载,那么 4MB/2=2MB.平均值是2MB.
Pss
是我们最常拿来做内存分析指标.
举例:
假设有程序A
和程序B
都被程序加载,操作分配一个虚拟存储空间给他们操作,大小为4G(这个就是Vss
),
然后程序A
和程序B
此时实际使用了内存了2G(Uss).
程序A
和程序B
加载同一动态库xxx.so
,而xxx.so
大小为1G,那么程序A
和程序B
的Rss
就是3G
计算xxx.so
平均值为 1G/2=0.5G.所以程序的Pss
的为2.5G
举例2:
Android
提供procrank
方便我们查看我们的所有程序(默认以Pss倒序排序)
脏页和干净页
页
的概念前面已经讲解过,而内存映射文件(Memory-mapped file)
也是页
单位进行映射的.假设某个代码在A页
,然后修改A页
里面的变量,那么这个页叫做脏页
.对于共享内存也是同理.
Android 内存管控机制
详细权威的可以查看官网 进程间的内存分配
下图是一个典型的Android内存模式,RAM
是内存,zRAM
也是RAM
,的一部分,而Storage
可以理解为我们的硬盘.
可能zRAM
大家并不了解,这里大致说下作用,当RAM
不足时,会将部分在RAM
内容压缩后放入zRAM
,等内存充足时解压zRAM
在放回RAM
.
内存不足策略1:kswapd
kswapd
是linux
的一个守护进程用于在内存不足将干净页
进行回收好腾出内存空间,而脏页
则会进行zRAM
压缩.这里非常好理解,如果是干净页
那么需要时再从文件读取即可,而脏页
因为修改过了和硬盘文件的不符合,无法从新读取.
内存不足策略2:LMK
kswapd
的回收和压缩机制并不能解决所有问题,所以Android还有另一个守护进程低内存终止守护进程(LMK/Low Memory Killer))
进行跟进一步的内存回收.LMK
会根据一个叫OOM_ADJ_SCORE
得到所有进程的优先级.(数值越低越不容易被杀死).
你可以通过:
cat proc/{pid}/oom_adj
来查看自己进程的优先级
oom_adj的数值一般根据以下图排序(高到低,越下面越不容易被杀死):
图来自官方文档,下面的说明简单修改官网文档
以下是上表中各种类别的说明:
后台应用:之前运行过且当前不处于活动状态的应用。LMK 将首先从具有最高 oom_adj_score 的应用开始终止后台应用。
上一个应用:最近用过的后台应用。上一个应用比后台应用具有更高的优先级(得分更低),因为相比某个后台应用,用户更有可能切换到上一个应用。
主屏幕应用:这是启动器应用。终止该应用会使壁纸消失。
服务:服务由应用启动,可能包括同步或上传到云端。
可觉察的应用:用户可通过某种方式察觉到的非前台应用,例如运行一个显示小界面的搜索进程或听音乐。可以简单理解用户可见APP,但是用户没有直接交互,比如有一个通知栏正在播放音乐
前台应用:当前正在使用的应用。终止前台应用看起来就像是应用崩溃了,可能会向用户提示设备出了问题。
持久性(服务):这些是设备的核心服务,例如电话和 WLAN。
系统:系统进程。这些进程被终止后,手机可能看起来即将重新启动。
原生:系统使用的极低级别的进程(例如,kswapd)。
在进行LMK
时会多次调用onTrimMemory(level: Int)
函数,参数level
告诉当前内存紧张状态,你可以通过level
的状态进行内存回收,否则你的app将被杀死.如果对于API 14的应用可以使用onLowMemory()
,相当于onTrimMemory
传入一个TRIM_MEMORY_COMPLETE
(当前已经准备扫描完所有LRU列表进程,如果内存还不足将杀死你的进程).
另外这里有一个注意点,你不应该直接==
判断level
,应该使用>=
或者<=
进行操作,因为android未来没准插入新的状态.
- 一个小Demo:
override fun onTrimMemory(level: Int) {super.onTrimMemory(level)//TRIM_MEMORY_UI_HIDDEN 用于告诉你,你应该回收ui视图,if (level>= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ) {rootView.removeAllViews()}}
常用技巧
getMemoryInfo()
MemoryInfo
可以通过getMemoryInfo
获取,通过MemoryInfo
我们更加细腻度掌握内存状态.
Demo(来自google官方):
public void doSomethingMemoryIntensive() {// Before doing something that requires a lot of memory,// check to see whether the device is in a low memory state.ActivityManager.MemoryInfo memoryInfo = getAvailableMemory();if (!memoryInfo.lowMemory) {// Do memory intensive work ...}}// Get a MemoryInfo object for the device's current memory status.private ActivityManager.MemoryInfo getAvailableMemory() {ActivityManager activityManager = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();activityManager.getMemoryInfo(memoryInfo);return memoryInfo;}
生成HEAP DUMP
am命令
使用pid:am dumpheap {pid} /data/local/tmp/fileName.hprof
使用package:am dumpheap {package} /data/local/tmp/fileName.hprof
代码
android.os.Debug.dumpHprofData("/sdcard/dump.hprof");
以上生成的heap dump可以拖入as自带的profiler进行分析
但是如果想使用JAVA之类的工具分析(MAT,jprofiler)需要hprof-conv
工具做下转化.
工具位于SDK目录:sdk/platform-tools/hprof-conv
- 使用demo:
hprof-conv in.hprof out.hprof
DDMS卡死等问题
ddms卡死jdk版本解决办法
参考
Android Memory Usage(英文)(注意pss描述不正确)
内存耗用:VSS/RSS/PSS/USS 的介绍
dumpsys文档
进程间的内存分配
Android内存相关相关推荐
- android 内核内存管理,Android内核相关内容总结
要想充分掌握Android这一操作系统的应用,首先需要我们从Android内核的相关内容开始了解.在这里就为大家详细介绍一下相关的知识. Android操作系统是由谷歌推出的一款基于Linux平台开源 ...
- android释放acitity内存,Android 内存泄漏分析与解决方法
在分析Android内存泄漏之前,先了解一下JAVA的一些知识 1. JAVA中的对象的创建 使用new指令生成对象时,堆内存将会为此开辟一份空间存放该对象 垃圾回收器回收非存活的对象,并释放对应的内 ...
- ANDROID内存优化(大汇总——中)
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 写在最前: 本文的思路主要借鉴了2014年AnDevCon开发者大会的一个演讲PPT,加上 ...
- Android内存泄漏就这样产生了
为什么80%的码农都做不了架构师?>>> 1.资源对象没关闭造成的内存泄漏 描述: 资源性对象比如(Cursor,File文件等)往往都用了一些缓冲,我们在不使用的时候,应该及 ...
- Android内存优化(三)避免可控的内存泄漏
相关文章 Android性能优化系列 Java虚拟机系列 前言 内存泄漏向来都是内存优化的重点,它如同幽灵一般存于我们的应用当中,有时它不会现身,但一旦现身就会让你头疼不已.因此,如何避免.发现和解决 ...
- Android 内存管理 amp;Memory Leak amp; OOM 分析
1.Android 流程管理&内存 Android主要应用在嵌入式设备其中.而嵌入式设备因为一些众所周知的条件限制,通常都不会有非常高的配置,特别是内存是比較有限的. 假设我们编写的代 码其中 ...
- Android Pmem相关介绍
http://fangjian0518.blog.163.com/blog/#m=0 Android Pmem相关介绍 2011-10-18 09:40:26| 分类: Android PMEM | ...
- Android内存管理
Android是一个基于Linux实现的操作系统.但对于Linux内核来说,Android也仅仅只是一个运行在内核之上的应用程序,与其他运行在内核之上的应用程序没有任何区别.所以Android需要一套 ...
- 【Android 内存优化】自定义组件长图组件 ( 长图滚动区域解码 | 手势识别 GestureDetector | 滑动计算类 Scroller | 代码示例 )
文章目录 一.GestureDetector 创建与设置 二.GestureDetector 触摸事件传递 三.触摸滑动操作 四.惯性滑动操作 五.长图滑动组件代码示例 六.运行效果 七.源码及资源下 ...
最新文章
- 逻辑模型三要素-数据结构
- Handler.removeMessages的作用,有时候为什么一定要先remove一下呢
- ansible-playbook剧本使用配置
- 3.1.9 二级页表
- kindeditor编辑器图片上传session丢失_微信公众号排版编辑器全指南!
- linux安装golang!!
- java的sas数据安全_使用sas中的do循环指定数据信息
- 电脑控制Android设备的软件——Total Control
- MongoDB最大连接数的查看与修改
- HP数组转JSON函数json_encode和JSON转数组json_decode函数的使用方法
- 基于UDP协议的Java聊天室
- inventor 波纹阵列_Inventor装配零部件阵列功能详解
- 转写给XJTU计算机系大一大二的童鞋
- PHP下制作图灵机器人程序
- 高级软件工程师必备的五大技能
- 小程序map组件一——使用腾讯地图个性化地图组件、腾讯云可视化大屏展示
- 数据结构堆栈 内存堆栈_零堆栈数据科学家第二部分秋天
- access数据库应用系统客观题_Access数据库选择题练习与答案
- mysql防火墙设置_mysql8 参考手册--MySQL企业防火墙配置参考
- post json数据
热门文章
- win10装系统时分区报错解决方法 无法找到新的分区也找不到现有分区
- STM32-UART串口应用
- [Unity] 战斗系统学习 9:构建 TPS 框架 4
- 鼎普计算机保密检查系统,敏感电子信息集中管控平台系统
- 做邮件服务系统的一点心得
- 【无标题】win11安装Oracle 12c [INS-32102] 指定的 Oracle 主目录用户已存在
- python 处理csv文件 一个简单的数据处理任务
- 线性代数第二章矩阵及其运算详解
- 速Geometric.Stackup.2.1.0.15228公差分析
- Java程序与以太坊智能合约交互