# Android性能优化-内存优化
很久之前写的了,发了吧,原用来总结学习的,再不发估计转行了,文章也参考了一些资料,抠用了一些图,主要是为了说明问题,总结学习
关于内存优化
首先,需要对android应用内存管理有所了解,即内存的开辟及回收,如此才能保证app一直有内存活下去
JAVA是在JVM所虚拟出的内存环境中运行的,内存分为三个区:堆、栈和方法区。
栈(stack):是简单的数据结构,程序运行时系统自动分配,使用完毕后自动释放。优点:速度快。
堆(heap):用于存放由new创建的对象和数组。在堆中分配的内存,一方面由java虚拟机自动垃圾回收器来管理,另一方面还需要在开发时候多注意,防止内存泄露问题。
方法区(method):又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。
关于内存回收,即java gc内存回收,回收堆中不用的对象
为什么要进行内存优化
1:app有运行内存上限,这里就会涉及到oom问题
2:内存抖动,影响app流畅度、响应速度和用户体验
3:内存泄露,程序通过new分配内存,在使用完毕后没有释放,造成内存占用。这块内存不受GC控制,无法通过GC回收。所以,会导致这块内存始终在那,又没法管理
方法 和 工具
在优化app内存时候用到的工具和方法,资料很多,还需要读者亲自去实践体验一下,不然,看过之后很快就忘了
- 获取app运行内存的方法:
app运行内存消耗超过这个限制,系统就会走崩溃的处理流程。。后面讲,如何解决该问题?
- as自带的工具
xxx
关于内存管理
android 系统内存分配与回收方式
底层linux
一个app通常就是一个进程对应一个虚拟机
查看app进程信息:
adb shell ps 或者 adb shell ps | grep 包名
dumpsys meminfo app包名
GC垃圾回收触发机制
对象,变量。不用了,会暂时放到垃圾堆里,并不会马上清理掉。只有再次向Heap请求空间时候发现内存不够了,才会触发gc去清理自己的垃圾堆。。
gc触发
gc触发时,所有的线程都会被暂停,并且gc是很耗cpu的
app内存限制机制
为什么要限制?
android是多任务系统,为了多app的公平,所以,就给每个app分配一定的内存,不能无限制的抢占内存
每个app分配的内存是有最大限制的,不同设备大小不同,这个对应关系在图片优化文章中有个表格可看下
吃内存大户:图片
系统分配给app的内存一般是够用的,如果出现内存不够用的现象,那么很大可能是图片处理优化的不好,因为现在手机像素很高,图片size很大
后台应用清理机制
app运行有前后台之分,android是多任务运行系统,前台只有一个,大部分任务还是后台运行的
后台任务的管理,系统用的是LRU Cache机制:即最近使用的排在最前面,最后被系统清理掉
系统触发内存清理时候,会调用应用的onTrimMemory()方法,就相当于是内存警告。表示你再不处理,即将很可能被杀掉清理掉,这时候可以将任务瘦身,该丢的就丢,保命要紧,你的内存降低后,被回收的可能性会有所降低的
监控内存的方法
- 1
- 2
android monitor 工具
- 3
tools - android - android device monitor sdk中bat运行 - 切换为devices模式
内存抖动
内存泄露
内存溢出
OOM问题
内存优化
数据结构优化
字符串的拼接
日常开发中,对于字符串的拼接,为了简单,直接使用”+“号进行拼接,这种方式,会产生中间字符串内存块,频繁的如此操作,会产生大量的中间字符串,并且低效,耗时长。建议使用StringBuilder进行字符串的拼接操作。。有兴趣可以实践一下,两种方式效率差别很大
低效的HashMap
HashMap效率是比较低的,建议使用ArrayMap、SparseArray代替。
- 内存占用较少
- 效率高
内存抖动
开发中,由于变成习惯不好,或逻辑质量不高带来的内存开销,导致app性能不高。表面看还算正常,但是这些不好的处理对于app长远发展来看始终是隐患
不要小看Class
再小的class都会耗费0.5KB,,所以,如果有大量的Class,也是可观的消耗,不过实际项目中这种情况极少出现,作为了解
多事的HashMap
HashMap中每个实体都会额外占用32B
对象复用
复用系统自带的资源
即使用系统原本带有的原生资源:包括view,图片,字符串,颜色,style等。可以进入\platforms\android-8\data\res查看
对象池????
享元模式 ????
item复用
关于listview,gridview,recyclerview的使用,方案已经比较成熟,包括在开发中使用的一些库,item复用,图片缓存等。
避免在onDraw方法里创建对象
ui视图有变动,就会执行onDraw,所以,这个方法执行的还是很频繁的,如果在其内部创建对象或耗时操作,ui操作就会显得卡顿,因为该方法内的对象一旦不被使用会快会被回收,都会导致一次或者多次垃圾回收,我们知道垃圾回收更加消耗CPU,会导致屏幕绘制时间减少,就有可能造成屏幕卡顿
避免内存泄漏
内存泄漏,说白了就是该回收的内存,系统去回收,发现还有”人“在用,gc就没法回收它。所以频繁的产生这类对象,可用的heap就越来越少
模拟gc,查看内存情况:
gc.png上下文
建议使用Application Context 而不是 Activity Context
Cursor及时关闭
数据库操作等,用完及时关闭
结语
开发能力需要一点点积累,当我们还不具备大神级别的架构能力和逻辑能力的时候,我们应该从搬砖中注意那些点点滴滴的高逼格技巧