我的原则:先会用再说,内部慢慢来。
学以致用,根据场景学源码
文章目录
- 一、概念与区别
- 二、架构
- 三、代码demo
- 3.1 强引用 Strong Reference
- 3.2 软引用 (SoftReference)
- 3.3 弱引用 (WeakReference)
- 4. 虚引用(PhantomReference)
- 四、番外篇
一、概念与区别
- Java中4种引用的强度由高到低依次为:强引用 -> 软引用 -> 弱引用 -> 虚引用
- 用途与区别:
引用类型 | 被垃圾回收时机 | 用途 | 生存时间 |
强引用 | 从来不会 | 对象的一般状态 | JVM停止运行时终止 |
软引用 | 当内存不足前 | 对象缓存 | 内存不足时终止 |
弱引用 | GC一看到立刻回收 | 对象缓存 | 垃圾回收后终止 |
虚引用 | 随时随刻 | 跟踪对象的垃圾回收 | 垃圾回收后终止 |
二、架构
=== 点击查看top目录 ===
三、代码demo
3.1 强引用 Strong Reference
- 生命周期:JVM 宁愿抛出OutOfMemoryError错误。
代码demo:
Object strongReference = new Object();
public void hello() {
Object strongReference = new Object();
// ...
}
GC回收时机:
- strongReference = null,那么无引用指向该 new Object()。
- 方法结束,java方法栈中局部变量被回收。
否则:JVM 宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会GC该对象来解决内存不足的问题。
=== 点击查看top目录 ===
3.2 软引用 (SoftReference)
- 生命周期:JVM 抛出OutOfMemoryError错误之前,回收这个软引用指向的对象堆内占用的空间。
目的:尽可能保留该对象,但是万不得已没内存的时候,可以进行回收
GC回收时机:
- strongReference = null,那么无引用指向该 new Object()。
- 方法结束,java方法栈中局部变量被回收。
- 堆内存不足,准备抛出OutOfMemoryError错误之前,处理一波软引用。
注意:软引用就算你调用 System.gc() 在内存充足的情况下,也不会回收这个对象的。
场景:浏览器的后退按钮。(缓存数据能保证加载快,但是内存不足的情况下,被回收了,重新去服务器加载也是可以接受的)
代码demo:
// 获取浏览器对象进行浏览
Browser browser = new Browser();
// 从后台程序加载浏览页面
BrowserPage page = browser.getPage();
// 将浏览完毕的页面置为软引用
SoftReference softReference = new SoftReference(page);
// 回退或者再次浏览此页面时
if(softReference.get() != null) {
// 内存充足,还没有被回收器回收,直接获取缓存
page = softReference.get();
} else {
// 内存不足,软引用的对象已经回收
page = browser.getPage();
// 重新构建软引用
softReference = new SoftReference(page);
}
=== 点击查看top目录 ===
3.3 弱引用 (WeakReference)
- 生命周期:GC一看到,立马消灭(首次看到标记,下次gc回收)
- 使用场景:
- 一个对象是偶尔(很少)的使用
- 一定程度上可以避免内存泄漏(详看 ThreadLocal类)
【线程】ThreadLocal 剖析 (十四)
- ThreadLocal.ThreadLocalMap.Entry
public class ThreadLocal<T> {
static class ThreadLocalMap {
static class Entry extends WeakReference<ThreadLocal<?>> {
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
}
}
- Thread
public java.lang.class Thread implements Runnable {
...
ThreadLocal.ThreadLocalMap threadLocals = null;
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
...
}
4. 虚引用(PhantomReference)
- 生命周期:任何时候都可能被GC回收 (如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收)
代码demo:
public class _03_00_TestPhamtonReference {
public static void main(String[] args) {
ReferenceQueue<String> referenceQueue = new ReferenceQueue<>();
PhantomReference<String> phantomReference = new PhantomReference<>("hello",referenceQueue);
System.out.println(phantomReference.get());
}
}
输出:
null
结论:
刚一出来就被消灭
=== 点击查看top目录 ===
四、番外篇
下一章节:【JAVA Reference】ReferenceQueue 与 Reference 源码剖析(二)