性能优化一直是高级Android工程师必问的,这也每每涉及到对Java、JVM、Android运行机制、监控工具使用等全方位的知识点,是很好的面试方向。面试
本篇会围绕Android与Java的性能优化专项之内存展开并深刻。数据库
内存是Android运行性能相当重要的一项指标,每一个进程能使用的内存是有限的。不合理的使用内存会致使频繁的GC、甚至发生OOM,过多GC会致使App卡顿,而内存泄漏或者内存抖动均可以致使OOM,这是没法接受的。缓存
所以,对于一个合格的高级Android工程师,必须保持对内存的高度敏感性,本文会针对内存提出一系列性能优化手段。性能优化
好比字符串拼接,能够手动使用StringBuilder,而不是使用"+","+"被编译器优化后会每次建立StringBuilder对象,形成浪费;函数
并且,尤为注意在主线程里不要过多建立对象。由于在GC时会锁住堆内存,此时请求分配的线程也会被挂起,这显然会致使主线程的卡顿。因此在一些主线程高频函数,如onDraw,onTouchEvent里不要去建立对象。工具
仍是StringBuilder的例子,基于一个StringBuilder能够经过SetLength(0)
支持不少次的字符串拼接。性能
多使用系统提供的对象池,好比线程池,Long、Integer、Short等包类型里的缓存值(经过valueOf取),列表view的复用等优化
内存一旦发生泄漏,意味着堆里有一块区域持续被再也不使用的变量占据,这天然会致使可用内存减小而发生gc,甚至OOM。ui
通常内存泄漏有几下几种状况:线程
通常是长生命周期的变量持有Activity引用,致使在gc时没法标记Activity从而没法回收,而Activity自己通常会引用到很是多的资源如View, Image,则这些大块资源均没法回收。
这种时候,咱们能够用WeakReference来弱引用;针对Activity这种场景可使用LeakCanary来进行监控,它会在Activity onDestroy后监控其引用是否被释放,若未释放则主动触发一次gc,gc后若是仍未释放,则会通知开发者。
静态变量通常是在装载类里的连接时进行内存分配,初始化时进行赋值。关键是,静态变量会伴随Android进程整个生命周期,若是引用了某块堆内存,则该内存没法被回收。单例也是相似。咱们在开发中不该该依赖太多静态变量和单例。
对于一些较大内存的对象,能够考虑利用finalize方法,防止在忘记释放时主动进行一些清理工做。像SQLiteDatabase、FileInputStream等都会在finalize方法里面进行一些清理工做,如关闭数据库。
不过,finalize方法并非万能的,它也会致使其余问题,后续再说。
Java里提供了四种引用: