强引用
作为初学者,我们平时用的Object obj=new Object();
就是强引用,这类引用在显示释放的时候才会为Null
Object strongReference = new Object();
只有当我们不使用这个对象,如下申明后才会被回收:
strongReference = null;
这里有几点需要注意:
- 在一个方法的内部局部变量一个强引用,这个引用保存在Java栈中,而真正的引用内容(Object)保存在Java堆中。当这个方法运行完成后,就会退出方法栈,则引用对象的引用数为0,这个对象会被回收。而如果我们将其return;这个时候,调用者会形成新的强引用;
- 但是如果这个方法中strongReference是全局变量时,不会被自动回收(大多情况下也不应该被回收)。
- 对于一些集合,使用
clear()
将集合内部清空,而=null
会让集合被释放 - 对于下面代码,a=null只是说明a指向null不引用自己new出来的obj了,但是b还是引用着这个Obj;所以b最终不等于
null
Obj a=new Obj();
b=a;
a=null;
强引用也是唯一可以一直存在直到手动释放的,下面三种引用的生命周期就不受自己控制了
软引用(SoftReference)
如果一个对象只具有软引用,那就类似于可有可无的生活用品。如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。
ReferenceQueue<String> referenceQueue = new ReferenceQueue<>();
String str = new String("abc");//str是abc强引用
SoftReference<String> softReference = new SoftReference<>(str, referenceQueue);//softReference就是abc的弱引用
str=null;//这个时候abc只有弱引用
System.gc();
System.out.println(softReference.get()); // abc
//强行使弱引用失效,模拟内存不足
Reference<? extends String> reference = referenceQueue.poll();
System.out.println(reference); //null,当内存不足,上一步不需要执行,也会null
弱引用
弱引用与软引用只有一点区别:只具有弱引用的对象拥有更短暂的生命周期。
在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。(所以没扫描到前还是存活的)
Object obj = new Object();
WeakReference<Object> weakObj = new WeakReference<Object>(obj);
obj=null; //手动释放只剩下一个weakObj弱引用
int i=0;
while(true){
if(weakObj.get()!=null){
i++;
System.out.println("Object is alive for "+i+" loops - "+weakObj);
}else{
System.out.println("Object has been collected.");
break;
}
}
output:
Object is alive for 1 loops - java.lang.ref.WeakReference@4554617c
...
Object is alive for 29721 loops - java.lang.ref.WeakReference@4554617c
Object has been collected.
执行到第29721次被扫描到回收了
虚引用
这个就是个完全没发言权的弟弟,引用了只是为了跟踪对象的生命周期,一旦对象只有虚引用,那就直接GC了;
String str = new String("abc");
ReferenceQueue queue = new ReferenceQueue();
// 创建虚引用,要求必须与一个引用队列关联
PhantomReference pr = new PhantomReference(str, queue);
str=null//这个时候直接GG
- 总结
引用类型 | 被垃圾回收时间 | 用途 | 生存时间 |
---|---|---|---|
强引用 | 从来不会 | 对象的一般状态 | JVM停止运行时终止 |
软引用 | 当内存不足时 | 对象缓存 | 内存不足时终止 |
弱引用 | 正常垃圾回收时 | 对象缓存 | 垃圾回收后终止 |
虚引用 | 正常垃圾回收时 | 跟踪对象的垃圾回收 | 垃圾回收后终止 |
参考:
https://blog.csdn.net/junjunba2689/article/details/80601729
https://blog.csdn.net/baidu_22254181/article/details/82555485