Java 四种引用:强、软、弱、虚
在 Java 中并不是所有对象都只有 “存活” 和 “死亡” 两种状态。通过不同强度的引用我们可以让 GC 灵活决定对象的生命周期这也是面试、缓存设计、内存优化中的高频考点。一、为什么要有四种引用Java 最开始只有强引用也就是我们平时写的Object obj new Object();但强引用太 “霸道”只要引用还在对象永远不会被回收。在很多场景下比如缓存我们希望内存够就留着内存不够就回收用完就丢只想监听对象回收于是 JDK 提供了4 种引用级别让我们可以手动控制对象和 GC 的关系。二、四种引用总览一句话速记强引用最常用宁 OOM 不回收软引用内存不足才回收适合缓存弱引用只要 GC 就回收生命周期极短虚引用拿不到对象只用来监听回收三、详细讲解 代码示例1. 强引用Strong Reference特点永不回收只要引用还在GC 绝不会碰它。平时new出来的对象全部都是强引用。User user new User(1, zhangsan);只要user指向该对象对象就一定不会被回收。即使内存不够JVM 直接抛OOM也不会回收强引用对象。示例public class StrongReferenceTest { public static void main(String[] args) { User user new User(1, zhangsan); User user1 user; user null; System.gc(); // 依然能拿到对象 System.out.println(user1); } }使用场景业务对象、实体类、所有正常创建的对象。2. 软引用SoftReference特点内存不足 → 才回收。在 JVM即将抛出 OOM 之前会把软引用关联的对象列入回收范围。如果回收后内存还不够才会 OOM。SoftReferenceUser softRef new SoftReference(new User(1, zhangsan));示例设置-Xms10m -Xmx10mpublic class SoftReferenceTest { public static void main(String[] args) { SoftReferenceUser userSoftRef new SoftReference(new User(1, zhangsan)); System.out.println(userSoftRef.get()); try { // 占用大内存迫使 JVM 回收软引用 byte[] b new byte[1024 * 1024 * 7]; } catch (Throwable e) { e.printStackTrace(); } finally { // 已经被回收 System.out.println(userSoftRef.get()); } } }使用场景内存敏感的高速缓存本地缓存、图片缓存、Netty、EHCache 等。3. 弱引用WeakReference特点只要发生 GC就直接回收。不管内存够不够只要 GC 执行只被弱引用指向的对象一定会被回收。WeakReferenceUser weakRef new WeakReference(new User(1, zhangsan));示例public class WeakReferenceTest { public static void main(String[] args) { WeakReferenceUser userWeakRef new WeakReference(new User(1, zhangsan)); System.out.println(userWeakRef.get()); System.gc(); // GC 后直接为 null System.out.println(userWeakRef.get()); } }使用场景临时缓存防止内存泄漏如 ThreadLocal、WeakHashMap4. 虚引用PhantomReference特点拿不到对象实例仅用于监听回收。虚引用也叫幽灵引用、幻影引用。永远无法通过get()获取对象必须配合ReferenceQueue使用唯一作用监听对象什么时候被回收ReferenceQueue queue new ReferenceQueue(); PhantomReferenceUser phantomRef new PhantomReference(new User(1, tom), queue);示例public class PhantomReferenceTest { public static void main(String[] args) throws InterruptedException { User obj new User(1, zhangsan); ReferenceQueueObject queue new ReferenceQueue(); PhantomReferenceObject phantomRef new PhantomReference(obj, queue); obj null; System.gc(); Thread.sleep(1000); // 判断是否被回收 System.out.println(对象是否被回收 phantomRef.isEnqueued()); } }使用场景监听对象回收做资源释放堆外内存管理Netty 等框架大量使用四、四种引用对比表面试直接背引用类型回收时机获取对象主要用途强引用永不回收能正常业务对象软引用OOM 前回收能内存敏感型缓存弱引用GC 就回收能临时缓存、防泄漏虚引用随时可回收不能监听回收、释放资源五、面试高频总结背完稳过强引用为什么会 OOM强引用只要存在GC 绝不回收内存不够直接 OOM。软引用和弱引用的区别软引用内存不足才回收。弱引用只要 GC 就回收。软引用适合做什么缓存防止 OOM。弱引用常见场景ThreadLocal、WeakHashMap。虚引用能干什么监听对象回收无法获取对象用于资源释放。哪种引用完全不影响 GC虚引用。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2426124.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!