面试题答案
一键面试场景一:缓存使用
- 场景描述:在使用WeakHashMap作为缓存时,如果缓存中的键对象在外部不再有强引用,但由于某些原因(如错误的业务逻辑导致未及时清理),值对象仍然被其他地方持有强引用。这样即便键被垃圾回收,值对象不会被回收,从而导致内存泄漏。例如,一个Web应用中缓存用户会话数据,会话对象作为键,相关业务数据作为值,若业务层错误地持有了值对象的引用,即使会话结束(键失去强引用),值仍无法释放。
- 防范措施:
- 定期清理:通过定时任务或事件监听机制,定期检查WeakHashMap,手动移除那些值对象已无必要保留的键值对。例如,在Web应用中,可以利用Servlet的监听器,在一定时间间隔内检查缓存,清理过期或无用的会话数据。
- 采用弱引用包装值:将值对象用WeakReference包装,这样当键被回收时,若值对象没有其他强引用,也会被回收。如
WeakHashMap<Key, WeakReference<Value>> weakHashMap = new WeakHashMap<>();
,使用时通过weakReference.get()
获取值对象。
场景二:对象生命周期管理
- 场景描述:在一个对象池的实现中使用WeakHashMap来管理对象。如果对象池中的对象在外部被释放(失去强引用),理论上WeakHashMap中的对应键值对应被回收。但如果对象池内部存在对这些对象的间接强引用,比如通过一些静态集合来跟踪对象状态等,就会导致对象无法被垃圾回收,出现内存泄漏。
- 防范措施:
- 解除内部强引用:确保在对象从对象池移除(键失去强引用)时,对象池内部及时解除对该对象的所有强引用。例如,在对象从WeakHashMap移除时,同时从用于跟踪状态的静态集合中移除该对象。
- 使用软引用代替内部强引用:对于需要在对象池内部跟踪的对象状态,可以使用SoftReference来持有对象,这样在内存不足时,这些软引用对象也会被回收,避免内存泄漏。