对Java中强引用、软引用、弱引用、虚引用的理解
摘要
极客时间里的Java核心技术系列,第4讲,记录一些笔记。
关键词:垃圾收集,引用计数,缓存,内存泄漏,可达性
铺垫
- 引用 可以用来 JVM的垃圾回收工作,通过引用判断 对象 是否存活。
- Java 堆中的对象,都有一个引用计数的属性,引用增加了1个,计数就加1。引用释放了1个,计数就减1。
- 从JDK1.2开始,把引用划分为4个等级,就是题目所写的4个。
- 所有引用类型,都是 java.lang.ref.Reference的子类。
里面有个 get() 方法,可以获取引用的对象。 但是幻象引用返回的 null,所以幻象引用必须和引用队列联合使用(否则它就没有存在的意义了)。
强引用
就是我们最常见的普通对象的引用。即使OOM错误了,程序也不愿回收它,但是我们可以显示的赋值为null,就是可以被垃圾回收的了(具体什么时候回收还要看算法)。
- 应用场景: (项目里到处都是。。。)
- ArrayList 里的 clear() 方法就是 对每个元素赋值为null,成为可回收的。
软引用
只有当 JVM 认为内存不足了,才会去回收它。
- 应用场景:
通常用来实现 内存敏感的缓存。
如果内存够,就保留缓存;如果内存不够了,就释放缓存。
弱引用
垃圾收集器的线程一旦扫描到了具有 弱引用 的对象,不管内存够不够,在下一次GC过程中,都会去回收它。
- 应用场景:
可以维护一种非强制性的映射关系。
试图去获取对象时,对象在,就使用它,否则重新实例化。
虚引用
也叫幻象引用。在任何时候都能被 垃圾收集器 回收。
仅仅是确保了对象被finalize之后,做某些事情的机制。
当垃圾收集器回收一个对象时,如果发现它有虚引用,就把他加入到相关联的引用队列中去,如果在引用队列里发现了相应的虚引用,就可以在所引用的对象被回收之前,做一些事情。
- 应用场景:
通常用来做所谓的 post-Mortem 清理机制。
Java 的不同可达性级别:
另外,也可以去尝试了解一下 reachabilityFence。
这将底层的一些能力暴露了出来,通过这些底层的API来达到强应用的效果。
参考链接:
https://juejin.im/post/5b82c02df265da436152f5ad
https://www.cnblogs.com/lingzhigege/p/11110272.html