Android 内存优化浅析
一:内存占用几大要点
1,Object Cache:Image cache,single instance obj(重量级别,例如数据库连接obj,bitmap ref),Thread过多,
2,View Ref过多:view 本身结构嵌套过多,过于复杂,background子元素image过多,使得单个view对象占有内存较多,如果View Container含有这实例对象过多,则会导致oom
3,组建Activity,service过多,也是会使app内存占用过高
4,leak Memmory:叠加效应导致内存异常占用
(简单叙述一下泄漏主因:全局成员变量引用(包括间接引用)components(Activity,Service,Broadcast,View及内部非static类),导致其无法回收资源),
5,有必要在合适的时候进行Trim cache
开发中注意以下几个方面:
(1)字符串拼接优化,减少字符串使用加号拼接,改为使用StringBuilder,初始化时设置capacity。
(2) 读文件优化 读文件使用ByteArrayPool,初始设置capacity,减少expand
(3) 资源重用,建立缓存池,对频繁申请、释放的对象类型重用
(4) 减少不必要或不合理的对象,例如在ondraw、getview中应减少对象申请,尽量重用。例如循环中不断申请局部变量等
(勿在循环调用的地方去产生对象,比如很多人不会注意的在getview里new onclicklistener(),这样的方式拖动的次数越多那么就会产生越多的对象。
当然还有在onDraw的地方newPaint等操作,这些都是需要避免的)
(5) 选用合理的数据格式 使用SparseArray,SparseBooleanArray, and LongSparseArray来代替Hashmap
Enum的内存消耗通常是static constants的2倍。应尽量避免在Android上使用enum,避免使用array 存储objects,(最好确定元素个数)
(6)Layout过于复杂,View频繁的触发measure、layout对View layout param进行频繁调整,例如动画效果,getview不同View gone visible param的调整
(7)同一时间动画执行的次数过多,View过度绘制,导致某些像素在同一帧时间内被绘制多次,从而使CPU或GPU负载过重;
(8)使用多进程,对于webview等,由于存在内存系统泄露或者占用内存过多的问题,我们可以采用单独的进程。微信放在单独的tools进程中
(9)动画问题:动画的每一帧渲染都是在UI线程的,如果有动画的时候进行耗时操作,很可能导致动画不流畅,掉帧问题,
耗时操作包括:
Layout:当动画正在播放的时候,要避免改变View(延迟改变);同时选择动画也需要避免会触发layout的动画,例如translation,scale等会导致延迟的layout操做。 Inflation:动画过程中避免inflate新的view,比如启动新的activity,或ListView(ScorllView)滑动到不同type的区域。
二:内存使用监控
1,GC日志监控
Dalvik Log Messages:
D/dalvikvm: <GC_Reason> <Amount_freed>, <Heap_stats>, <External_memory_stats>, <Pause_time>
example
D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/5261K, paused 2ms+2ms
通过GC log看到每次回收多少,可以内存剩余多少,这里重点关注GC_Reason,
GC_CONCURRENT
内存使用到达目标使用率(系统会有一个目标使用率例如,45%)时,开时回收内存(A concurrent GC that frees up memory as your heap begins to fill up).
GC_FOR_MALLOC
剩余内存不足,小于对象申请使用内存大小,此时暂停程序所有线程,开始清理回收内存
(A GC caused because your app attempted to allocate memory when your heap was already full, so the system had to stop your app and reclaim memory.)
GC_HPROF_DUMP_HEAP
dump hprof时,引起内存回收(A GC that occurs when you request to create an HPROF file to analyze your heap.)
ART Log Messages
I/art : Explicit concurrent mark sweep GC freed 104710(7MB) AllocSpace objects, 21(416KB) LOS objects, 33% free, 25MB/38MB, paused 1.230ms total 67.216ms
Concurrent
(并发回收,垃圾回收不影响程序运行)
A concurrent GC which does not suspend app threads. This GC runs in a background thread and does not prevent allocations.
Alloc
(程序申请内存,内存不够时触发)
The GC was initiated because your app attempted to allocate memory when your heap was already full. In this case,
the garbage collection occurred in the allocating thread.
Explicit
(调用System.gc()触发,没啥实际用途)
The garbage collection was explicitly requested by an app, for instance, by calling gc() or gc(). As with Dalvik,
in ART it is recommended that you trust the GC and avoid requesting explicit GCs if possible.
NativeAlloc
(jni层进行内存申请时触发)
The collection was caused by native memory pressure from native allocations such as Bitmaps or RenderScript allocation objects.
2,Runtime监控
Runtime.getRuntime().maxMemory();
long leaveMemmory= Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory();
//我们可以定期(前台每隔3分钟)去得到这个值,当我们这个值达到危险值时(例如85%)手动清理资源
3,Compoment onMemmoryTrim()回调监控,涉及到Android内存回收策略
系统内存回收策略:我们知道当应用不再使用退出后,系统不会立即终止掉该app进程而是将它缓存起来(方便下次快速启动),当系统内存不够使用时,
system会按照process优先级别进行处理,这个process列表使用LRU(last recently used)规则处理
process分类:引用文档一段描述
(1)foreground process what the user is currently doing
(2)visible process holding an Activity that is visible to the user on-screen but not in the foreground (its onPause() method has been called).
the foreground Activity is displayed as a dialog
(3)service process holding a Service that has been started
(4)background process holding an Activity that is not currently visible to the user (its onStop() method has been called).
(5)empty process that doesn't hold any active application components.(application quit)
@Override
public void onTrimMemory(int level) {
//Called when the operating system has determined that for a process to trim unneeded memory from its process
//内存不够新程序内存申请时,开始回收,callback this method
switch(level){
case TRIM_MEMORY_COMPLETE:
//process is nearing the end of the background LRU list(LRU后台进程列表中最后进程,内存不足时会被杀死)
break;
case TRIM_MEMORY_MODERATE:
//process is around the middle of the background LRU list(LRU后台进程列表中中间进程,内存不足时可能会被清理)
case TRIM_MEMORY_BACKGROUND:
//process has gone on to the LRU list(程序进入后台LRU列表)
break;
case TRIM_MEMORY_UI_HIDDEN:
//process had been showing a user interface, and is no longer doing so (程序对用户不可见,UI不在对用户可见,此时应该released UI resource)
case TRIM_MEMORY_RUNNING_CRITICAL:
//the device is running extremely low on memory and is about to not be able to
//keep any background processes running(LRU后台Process已全部清理,可用内存依然很低不够使用,此时需要当前程序手动释放资源,缓存,图像,不可见view等)
case TRIM_MEMORY_RUNNING_LOW:
break;
}
super.onTrimMemory(level);
}
总结:
1,在平时编写代码时注意已经明确出会产生内存问题代码写法
2,注意模块内存泄漏监测,Allocation Tracker,Leankcanary
3,Compoment内根据其生命周期,进行资源释放控制,例如:Activity onpause,onResume注册,解除注册
4,内存警戒值检测,当达到预警值释放,image,object cache等清理,多个Activity会有很多后台view 并不对用户可见,此时也可以释放掉,
数据存盘,View至空处理,当页面返回时重新加载view
5,设计时候减少后台资源
参考
https://developer.android.com/studio/profile/investigate-ram.html
http://mp.weixin.qq.com/s?__biz=MzAwNDY1ODY2OQ==&mid=400656149&idx=1&sn=122b4f4965fafebf78ec0b4fce2ef62a&scene=23&srcid=0701zlpPcKRDEIZB7BRu3bdj#rd
Android 内存优化浅析的更多相关文章
- 【腾讯Bugly干货分享】Android内存优化总结&实践
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/2MsEAR9pQfMr1Sfs7cPdWQ 导语 智 ...
- Android内存优化1 了解java内存分配 1
开篇废话 今天我们一起来学习JVM的内存分配,主要目的是为我们Android内存优化打下基础. 一直在想以什么样的方式来呈现这个知识点才能让我们易于理解,最终决定使用方法为:图解+源代码分析. 欢迎访 ...
- 大礼包!ANDROID内存优化(大汇总)
写在最前: 本文的思路主要借鉴了2014年AnDevCon开发者大会的一个演讲PPT,加上把网上搜集的各种内存零散知识点进行汇总.挑选.简化后整理而成. 所以我将本文定义为一个工具类的文章,如果你在A ...
- ANDROID内存优化——大汇总(转)
原文作者博客:转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! ANDROID内存优化(大汇总——上) 写在最前: 本文的思路主要借鉴了20 ...
- Android内存优化之——static使用篇(使用MAT工具进行分析)
这篇文章主要配套与Android内存优化之——static使用篇向大家介绍MAT工具的使用,我们分析的内存泄漏程序是上一篇文章中static的使用内存泄漏的比较不容易发现泄漏的第二情况和第三种情况—— ...
- ANDROID内存优化(大汇总——中)
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 写在最前: 本文的思路主要借鉴了2014年AnDevCon开发者大会的一个演讲PPT,加上 ...
- Android内存优化(三)详解内存分析工具MAT
前言 在这个系列的前四篇文章中,我分别介绍了DVM.ART.内存泄漏和内存检测工具的相关知识点,这一篇我们通过一个小例子,来学习如何使用内存分析工具MAT. 1.概述 在进行内存分析时,我们可以使用M ...
- Android内存优化(二)DVM和ART的GC日志分析
相关文章 Android内存优化系列 Java虚拟机系列 前言 在Java虚拟机(三)垃圾标记算法与Java对象的生命周期这篇文章中,提到了Java虚拟机的GC日志.DVM和ART的GC日志与Java ...
- Android内存优化(一)DVM和ART原理初探
相关文章 Android内存优化系列 Java虚拟机系列 前言 要学习Android的内存优化,首先要了解Java虚拟机,此前我用了多篇文章来介绍Java虚拟机的知识,就是为了这个系列做铺垫.在And ...
- Android内存优化大全(中)
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 写在最前: 本文的思路主要借鉴了2014年AnDevCon开发者大会的一个演讲PPT,加上 ...
随机推荐
- .Net简单使用了一下Redis
书接上回!!! 创建控制台应用 管理NuGet程序包 下载ServiceStack.Redis 最后写代码 1 class Program 2 { 3 static RedisClient redis ...
- myql数据库新建之后,本地可以访问,远程访问不了
通过如下命令去修改: use mysql; update user set user.Host='%' where user.User='root'; flush privileges;
- (前端面试题)详解 JS 的 setTimeout 和 setInterval 两大定时器
程序员面试题库分享 1.前端面试题库 (面试必备) 推荐:★★★★★ 地址:前端面试题库 2.前端技术导航大全 推荐:★★★★★ 地址:前端技术导航大全 3.开发者颜色 ...
- 浅谈hive
hive支持sql标准的数据仓库,可以将sql语句转化成mr程序执行.基础分析一般用hive来做,比较复杂的用mr来做数据仓库和数据库的区别 数据仓库:历史数据,面向分析,保证数据的完整性可以允 ...
- linux top 指令各列含义
Linux 的 top 指令用于显示机器上正在运行的进程的信息.下面是 top 指令各列的含义: PID:进程 ID,用于标识进程. USER:进程所有者的用户名. PR:进程优先级. NI:进程的& ...
- 洛谷P8924题解
洛谷 P8924 题解 题目描述 给你一个函数,画出它的函数图像(* 表示经过该点,. 表示不经过该点),大小为 \(n\times m\),其中 \(x\) 的范围是 \([0,n-1]\),\(f ...
- .NET CORE-Auto整合至MVC中
在Program.cs中使用Autofac工厂去替代默认工厂: public static IHostBuilder CreateHostBuilder(string[] args) => Ho ...
- GPS北斗卫星时钟同步系统提升电信支撑网性能
GPS北斗卫星时钟同步系统提升电信支撑网性能 京准科技提供参考--更多资料VX(ahjzsz) 各项新的数据业务,如电子商务.多媒体通信.IP电话等都是电信业务发展的新增长点,而传统业务也存在多家企业 ...
- 教你如何自己搭环境部署华为FusionCompute虚拟化系统
https://www.bilibili.com/video/BV1iy4y177f4?p=10 实用的干货快先码起来,说不定以后会用到哟
- A Novel Cross-domain Access Control Protocol in Mobile Edge Computing
摘要 随着智能移动终端和移动通信技术的发展,移动边缘计算(MEC)已经应用到各个领域.然而,MEC也带来了新的数据安全威胁,包括数据访问威胁.针对MEC中的跨域访问控制问题,提出一种跨域访问控制协议C ...