面试题答案
一键面试弱引用(WeakReference)
- 应用场景:
- 适用于创建一些非关键且容易重新创建的对象,当系统内存不足时,这些对象可以被垃圾回收器随时回收。例如,在缓存场景中,如果缓存中的数据可以从其他数据源轻易重新获取,就可以使用弱引用。这样当内存紧张时,缓存中的数据会被优先回收,避免内存溢出。
- 常用于解决对象的生命周期管理问题,比如在对象的生命周期不应该影响其被引用对象的生命周期时,像观察者模式中,当被观察对象不再被强引用时,希望观察者也能被及时回收,就可以使用弱引用。
- 避免内存溢出:通过允许垃圾回收器在内存紧张或正常垃圾回收时回收弱引用指向的对象,释放内存空间。例如在大量图片加载的应用中,如果使用强引用保存图片对象,可能会导致内存溢出。使用弱引用保存图片对象,当内存不足时,图片对象会被回收,从而避免内存溢出。
- 高并发下的正确使用:
在高并发场景下,需要注意对import java.lang.ref.WeakReference; import java.util.HashMap; import java.util.Map; public class WeakReferenceExample { private static Map<String, WeakReference<byte[]>> cache = new HashMap<>(); public static byte[] getFromCache(String key) { WeakReference<byte[]> weakReference = cache.get(key); if (weakReference != null) { return weakReference.get(); } return null; } public static void putToCache(String key, byte[] data) { cache.put(key, new WeakReference<>(data)); } }
cache
的操作可能存在线程安全问题。可以使用ConcurrentHashMap
来替代HashMap
,保证线程安全。
软引用(SoftReference)
- 应用场景:
- 适用于缓存一些相对重要但可以在内存不足时释放的对象。例如,在浏览器中缓存网页内容,当内存充足时,网页内容可以一直保留在缓存中,提高访问速度;当内存不足时,缓存的网页内容会被回收。
- 对于一些创建开销较大,但又不是必须一直存在内存中的对象,如数据库连接池中的连接对象,在内存紧张时可以被回收,下次使用时再重新创建。
- 避免内存溢出:软引用指向的对象只有在系统内存不足时才会被垃圾回收器回收,这样可以在保证应用正常运行的前提下,尽可能利用内存空间。例如在一个大数据处理应用中,处理中间结果可能占用大量内存,使用软引用保存这些中间结果,当内存不足时,这些中间结果会被回收,从而避免内存溢出。
- 高并发下的正确使用:
同样,在高并发场景下,import java.lang.ref.SoftReference; import java.util.HashMap; import java.util.Map; public class SoftReferenceExample { private static Map<String, SoftReference<byte[]>> cache = new HashMap<>(); public static byte[] getFromCache(String key) { SoftReference<byte[]> softReference = cache.get(key); if (softReference != null) { return softReference.get(); } return null; } public static void putToCache(String key, byte[] data) { cache.put(key, new SoftReference<>(data)); } }
cache
的操作也存在线程安全问题,可使用ConcurrentHashMap
替代HashMap
以确保线程安全。同时,在使用软引用时,要注意对软引用对象的获取和处理,因为对象可能已经被回收,需要进行相应的判断。