Android开发经验谈Android技术知识Android开发

# Android性能优化-内存优化

2020-07-02  本文已影响0人  DaZenD

很久之前写的了,发了吧,原用来总结学习的,再不发估计转行了,文章也参考了一些资料,抠用了一些图,主要是为了说明问题,总结学习

关于内存优化

首先,需要对android应用内存管理有所了解,即内存的开辟及回收,如此才能保证app一直有内存活下去

JAVA是在JVM所虚拟出的内存环境中运行的,内存分为三个区:堆、栈和方法区。
栈(stack):是简单的数据结构,程序运行时系统自动分配,使用完毕后自动释放。优点:速度快。
堆(heap):用于存放由new创建的对象和数组。在堆中分配的内存,一方面由java虚拟机自动垃圾回收器来管理,另一方面还需要在开发时候多注意,防止内存泄露问题。
方法区(method):又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。

关于内存回收,即java gc内存回收,回收堆中不用的对象

为什么要进行内存优化

1:app有运行内存上限,这里就会涉及到oom问题

2:内存抖动,影响app流畅度、响应速度和用户体验

3:内存泄露,程序通过new分配内存,在使用完毕后没有释放,造成内存占用。这块内存不受GC控制,无法通过GC回收。所以,会导致这块内存始终在那,又没法管理

方法 和 工具

在优化app内存时候用到的工具和方法,资料很多,还需要读者亲自去实践体验一下,不然,看过之后很快就忘了

getmemory.png

app运行内存消耗超过这个限制,系统就会走崩溃的处理流程。。后面讲,如何解决该问题?

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()方法,就相当于是内存警告。表示你再不处理,即将很可能被杀掉清理掉,这时候可以将任务瘦身,该丢的就丢,保命要紧,你的内存降低后,被回收的可能性会有所降低的

监控内存的方法

monitormemory1.png

android monitor 工具

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等。可以进入android-sdk\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及时关闭

数据库操作等,用完及时关闭

结语

开发能力需要一点点积累,当我们还不具备大神级别的架构能力和逻辑能力的时候,我们应该从搬砖中注意那些点点滴滴的高逼格技巧

上一篇下一篇

猜你喜欢

热点阅读