一、强/软/弱/虚引用
- 强应用
当新建的对象为强引用时,垃圾回收器绝对不会回收它。宁愿跑出OutOfMemoryError异常,让程序异常终止也不会回收 - 软引用
当新建的对象为软引用时,当内存不够时,回收器就会回收这些对象,如果回收后还是没有足够的内存,跑出OutOfMemoryError异常 - 弱引用
当新建的对象为弱引用时,垃圾回收器不管当前内存是否足够,都会回收它的内存 - 虚引用
虚引用跟其他引用都不同,如果一个对象仅持有虚引用,在任何时候都可能被GC回收,只是当它被回收时会受到一个系统通知
二、垃圾回收机制
-
标记算法
- 引用计数算法
缺点:对象如果重复引用就会导致计数器无法成为0,也就会导致对象无法回收 - 可达性分析算法:
以GC-Root为七点,只要在链条上,都是有效对象
- 引用计数算法
-
清除算法
- 标记清除算法
缺点 :有内存碎片存在。效率比较低(循环所有的对象) - 复制算法
优点:效率比较高,没有内存碎片存在
缺点:java堆的内存空间被挤压,无法承载大量的对象 - 标记压缩算法:
优点:没有内存碎片;空间承载量比较大
缺点:效率一般 - 分代垃圾收集算法
将复制算法应用到分带垃圾算法;分为新生代和老年代,根据对象的生命周期进行处理
- 标记清除算法
三、内存泄漏
当一个对象在java堆中应该被回收时,而没有被回收,这个对象就可以称为内存泄漏
处理Handler内存泄漏的解决方案
- 使用softreference
缺点:是一定要在内存不足的情况下才会回收;如果内存一直足,这个内存泄漏就一直存在 - 使用weakreference
缺点:垃圾回收机制一过来,就会回收;根据业务需求,如果要调用activity的某些方法,activity被回收了,跟业务需求不符合 - 使用static关键字;
没有使用static关键字时,内存泄漏的原因是handler引用了activity(默认内部类引用外部类)static关键字会破坏handler成为一个内部类。
缺点:消耗内存过大,加载效率慢 - 直接在onDestroy移除handler
可能引起内存泄漏的原因
- 单例造成的内存泄漏
能使用Application的context尽量使用ApplicationContext - 非静态内部类造成的内存泄漏(比如handler)
- 外部类中持有非静态内部类的静态对象
- Handler 或 Runnable 作为非静态内部类
- 监听器没有及时取消注册
- 资源对象未及时关闭(BraodcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap等)
- WebView