Java 内存泄漏
虽然Java有GC垃圾自动回收功能,但并不是说Java程序就不会内存泄漏。如果一个对象没有地方会使用到,但是却仍然有引用指向他,那么垃圾回收器就无法回收他,这种情况就属于内存泄漏。这种泄漏可能属于短暂的(即程序运行一段时间后引用消除进而出发GC)也可能是程序级别的(即程序退出时才会回收)。Java的内存泄漏和C/C++的内存泄漏不一样,C/C++的内存泄漏可能是系统级别的,即使程序退出也无法被回收,只能重启系统。
Android系统为每个程序分配了固定大小的堆,当使用超过堆内存的时候,便会触发OOM,因此在开发android程序时,控制堆的分配释放,在以下情况下分配对象要格外注意。
1.静态对象的生命周期是程序级别的,当引用了静态对象或者静态对象里面引用了堆上的对象的时候,这些对象的生命周期就和该静态对象一样长。
2.作为内部类的线程(包括AsyncTask),由于线程的运行周期和所在对象的周期不一致,运行的线程默认会拥有所在对象的引用,所以线程运行时销毁其所在的对象并不会真正的回收,而是等到线程退出之后才会执行。
3.注册某个对象后没有反注册。
4.资源对象应该及时关闭,比如(cursor,file),这类对象往往不仅拥有Java堆内存还有Native堆内存,所以不用时需要close();
上面这些容易导致内存泄漏放而引起OOM,下面的情况则是减少OOM放生的几率
1. Bitmap分配按需要的大小分配,并及时销毁,由于Bitmap往往占用内存很大,而且部分是native的,加上GC的时机受系统影响,若是没 及时释放销毁Bitmap,则会导致内存使用过度引起OOM
2. 使用SoftRefrence,当内存紧张时,这类对象会被有效的释放
3. 减少内存分配和释放带给系统的压力,比如在Adapter中getView时,通过ViewHolder对View的重用