面试题答案
一键面试对象生命周期与引用类型关系
- 强引用(Strong Reference)
- 关系:在Kotlin Android开发中,正常声明对象的方式就是强引用。只要对象有强引用指向它,对象就不会被垃圾回收,即使内存紧张。这意味着对象的生命周期会一直持续到没有任何强引用指向它为止。
- 示例:
这里val strongRef: MyObject = MyObject()
strongRef
就是对MyObject
实例的强引用,只要strongRef
还在作用域内,MyObject
实例就不会被回收。 - 软引用(Soft Reference)
- 关系:软引用指向的对象只有在内存不足时才会被垃圾回收。它可以让对象在内存充足时保持存活,延长对象生命周期,当系统内存紧张时,垃圾回收器会回收这些软引用指向的对象,从而释放内存。
- 示例:
在图片缓存场景中,如果内存充足,软引用指向的图片对象会保持存活,当内存紧张时,图片对象可能会被回收,这样可以避免OOM(Out Of Memory)。val softRef = SoftReference(MyObject()) val myObj = softRef.get() if (myObj!= null) { // 使用myObj } else { // 对象已被回收,重新创建或处理 }
- 弱引用(Weak Reference)
- 关系:弱引用指向的对象只要发生垃圾回收,无论当前内存是否充足,都会被回收。它的生命周期非常短暂,一旦垃圾回收器扫描到只有弱引用指向的对象,就会回收该对象。
- 示例:
在避免内存泄漏场景中,比如Activity与某个监听器的关系。如果监听器持有Activity的强引用,当Activity销毁时,由于监听器未释放,Activity无法被回收导致内存泄漏。使用弱引用可以解决这个问题,监听器持有Activity的弱引用,当Activity销毁时,垃圾回收器可以回收Activity对象。val weakRef = WeakReference(MyObject()) val myObj = weakRef.get() if (myObj!= null) { // 使用myObj } else { // 对象已被回收,重新创建或处理 }
- 虚引用(Phantom Reference)
- 关系:虚引用也叫幻影引用,它是最弱的一种引用关系。虚引用指向的对象和没有任何引用指向的对象一样,在任何时候都可能被垃圾回收。虚引用主要用于跟踪对象被垃圾回收的状态。
- 示例:
在一些资源清理场景中,比如Native资源的释放,当对象被回收时,通过虚引用和引用队列可以得知对象已被回收,从而触发Native资源的释放操作。val refQueue = ReferenceQueue<MyObject>() val phantomRef = PhantomReference(MyObject(), refQueue) val myObj = phantomRef.get() // 永远返回null val polledRef = refQueue.poll() if (polledRef!= null) { // 说明MyObject已被回收 }
不同业务场景下的使用
- 图片缓存
- 使用软引用:在图片加载框架中,对于内存中的图片缓存可以使用软引用。当内存充足时,图片对象会保持在缓存中,下次加载相同图片时可以直接从缓存获取,提高加载速度。当内存紧张时,软引用指向的图片对象会被回收,释放内存,避免OOM。
- 避免内存泄漏
- 使用弱引用:在自定义View或者监听器等场景中,如果这些对象持有Activity或Fragment的引用,为了避免Activity或Fragment销毁时无法被回收导致内存泄漏,可以使用弱引用。比如一个自定义View需要监听Activity的一些生命周期事件,自定义View持有Activity的弱引用,当Activity销毁时,自定义View中的弱引用不会阻止Activity被回收。
- 资源清理
- 使用虚引用:在涉及到Native资源(如OpenGL的纹理等)的管理时,使用虚引用。当Java对象被回收时,通过虚引用和引用队列可以得知对象已被回收,进而触发Native资源的释放操作,确保资源被正确清理。