一个Android手机的内存是有限的,所以APP默认分配内存大小也是有限的。
在Android里,程序内存被分为2部分:
native和dalvik,dalvik就是我们普通的Java使用内存,我们创建的对象是在这里面分配的,对于内存的限制是 native+dalvik 不能超过最大限制。android程序内存一般大部分限制在16M,也有的一小部分是24M。所以合理的利用内存在我们的公工作中就会变得很长重要。
gDvm.heapSizeStart = 2 * 1024 * 1024; // heap初始化大小为2M
gDvm.heapSizeMax = 16 * 1024 * 1024; // 最大的heap为16M
其实项目中内存问题大部分出现在内存泄露和内存溢出中,前者占了大多数。
以下列举问题以及解决方案:
-
Handler引起的内存泄露。
解决方案:将Handler声明为静态内部类,就不会持有外部类Activity的引用,其生命周期就和外部类无关,如果Handler里面需要context的话,可以通过WeakReference引用方式引用外部类。
另一种方式可以在UI退出之前,执行remove Handler消息队列中的消息与runnable对象。
-
单例模式引起的内存泄漏。
解决方案:Context是ApplicationContext,由于ApplicationContext的生命周期是和app一致的,不会导致内存泄漏。
-
非静态内部类创建静态实例引起的内存泄漏。
解决方案:把内部类修改为静态的就可以避免内存泄漏。
-
注册/反注册未成对使用引起的内存泄漏。
解决方案:注册广播接受器、EventBus等,记得解绑注销。
-
资源对象没有关闭引起的内存泄漏。
解决方案:资源不使用的时候,记得调用相应的类似 游标close()、destroy()、recycler()、release()等方法释放。
-
集合对象没有及时清理引起的内存泄漏。
解决方案:当不使用的时候一定要记得及时清理集合,让相关对象不再被引用。
-
WebView 存在着内存泄漏的问题。
解决方案:把WebView放在一个容器里,在UI退出之前即时释放它。
查看内存的工具:
LeackCanary: 谷歌提供 内存泄露
Memory Monitor 可以很好地监控系统或应用的内存使用情况.
Heap Viewer: Heap Viewer 的功能是查看不同数据类型在内存中的使用情况,可以看到当前进程中的 Heap Size 的情况,分别有哪些类型的数据,以及各种类型数据占比情况。
Allocation Tracker: Memory Monitor 和 Heap Viewer 都可以很直观且实时地监控内存使用情况,还能发现内存问题,但发现内存问题后不能再进一步找到原因,或者发现一块异常内存,但不能区别是否正常,同时在发现问题后,也不能定位到具体的类和方法。
Memory Analyzer Tool(MAT): MAT 是一个快速,功能丰富的 Java Heap 分析工具,通过分析 Java 进程的内存快照 HPROF 分析,从众多的对象中分析,快速计算出在内存中对象占用的大小,查看哪些对象不能被垃圾收集器回收,并可以通过视图直观地查看可能造成这种结果的对象。
参考:
android APP性能优化总结
Android性能全面分析与优化方案研究—几乎是史上最全最实用的