3:安卓性能优化之内存优化
-
为什么要做内存优化?
如果不优化内存,1)app运行内存是有限制的,因为安卓手机是多任务系统同时运行多个app,不做限制,一个app运行吃光内存,其它app就运行不了,应用分配的内存要么256m,要么512m。超出这个限制大小,就会oom。2)内存占用太大不做优化,在流畅性,响应速度,用户体验上都会有较大影响。
-
安卓内存的管理方式
2.1)安卓系统内存分配方式和回收方式
2.2)app内存限制机制,app运行吃内存大户是图片。
2.3)切换应用时,后台app清理机制。App前后台切换时,用的LRUCache算法,最近使用的排在最前面,最少可能被清理掉。运行app太多,内存不够时,后台应用清理顺序由后往前清理。当系统内存有变化时,系统会通过onTrim
Memory()发出通知给各个应用,收到此通知,如果系统内存很少了,代表系统要清理后台的app了。这时候你做相应的处理,把你的app里面不用的内存尽快清理释放掉,这样你app内存占用就会小一点。从而可能被慢些清理。
2.4)监控内存的几种方法,app运行先只会分配一部分内存,其中会剩余一部分内存,但内存不够时再分配一部分内存,能分配到的总内存,不会超过最大内存。
2:内存泄漏:堆中存在不再被使用的对象因为有引用存在不能被垃圾回收器回收,就是内存泄露。(比如:我们vm层对repo层的引用在界面销毁时,其实是释放了的,因为vm是成员变量持有repo对象,而view层只是局部变量接收vm对象,所以没有持有vm层的引用),造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等后果。用户可使用的内存空间分为以下3部分:
-
静态存储区:一直会存在,不会消失,一般为全局变量,静态变量和常量。存于方法区
-
动态存储区:是代码执行过程中,根据需要动态分配和动态释放的存储单元。包括局部变量,形参和函数调用时的现场保护与返回地址。包括堆和栈
-
程序存储区:存放函数体的二进制代码。
-
静态成员变量,是共享数据,存于共享区,即方法区中。
-
非静态成员变量,在堆内存中,作用于整个类。
-
形参,局部变量存于栈中,属于动态存储区。
所以,类中成员变量,在销毁时,都建议置空,不需要成员变量放置的view,全部写成局部变量。
1:引用持有:在一个类中访问另一个类的成员变量或者方法,通过持有另一个类的引用来访问。
-
强引用StrongReference:强引用不会被垃圾回收器回收,即使当前内存空间不足,jvm也不会回收它,而是抛出OOM,使程序异常终止。取消强引用将其赋值为null,jvm在合适的时机会回收。
强引用具体包括哪些?
A类要访问B类中的方法或者成员变量,就会new B类的对象,这就是强引用。私有静态内部类B2一般都用弱引用嵌套A1类设置对象,访问A1类中的变量和方法。
-
软引用SoftReference:内存空间足够的时候,不会被垃圾回收器回收,只有在内存空间不足时,软引用才会被垃圾回收器回收。可以手动调用System.gc();回收垃圾调试
-
弱引用WeakReference:当jvm做垃圾回收或者手动调用System.gc(),一旦发现弱引用对象,不论内存空间是否充足,都会将弱引用回收。不过垃圾回收是一个优先级较低的现象,所以不能迅速回收弱引用对象。
-
虚引用PhantomReference:相当于没有引用,任何时候都可能被垃圾回收器回收。