大家在编码过程中或多或少都有用过,这篇文章就是要对这些常用的引用进行记录,作为学习笔记。
这些定义的不同和引用对象的生命周期有关。
一、强引用
static Object strongRef= new Object();
public static void main () {
Object obj = strongRef;
strongRef = null;
System.gc();
System.out.println(obj);
}
由于obj是强引用,所以并不会在System.gc()后就被回收。
原因:静态成员变量在类被卸载后才会被销毁,类只有在进程被销毁后才会被销毁,那么到时候该对象才会被gc处理。
总结:强引用的回收机制
1、拖离作用域:main方法回收完之后,obj才会被回收。
2、对象被设置成null:在gc之前将obj = null,那么触发gc后,obj就会被回收。
二、软引用
使用软引用的对象,只有在程序发生OOM(out of memory)异常之前,才会不回收。所以如果内存充足的情况下,这个对象是不会被回收。这样就可以避免OOM异常。
java中提供了一个软引用的api,叫做SoftReference(),只有使用这个接口才表示是软引用。
public static void main(String[] args) {
String name = new String("hepheastushao");
SoftReference softRef = new SoftReference(name);
name = null;// 不会被回收
softRef = null;// 只有在改软引用对象被置空,才会被回收
System.out.println(softRef.get());
}
总结:强引用和软引用在gc之后都不会被回收,软引用只有系统报出OOM才会被回收,强引用在OOM之后也不会被回收,只有在进程消亡之后才会被回收。
三、弱引用
在gc回收后,弱引用就会被回收。
public static void main(String[] args) {
String name = new String("hepheastushao");
WeakReference weakRef = new WeakReference(name);
name = null;
System.gc();
System.out.println(weakRef .get());// 已经被回收
}
弱引用的回收:1、对象被置为null;2、执行gc之后。但是当name对象是常量,那么不会被回收,因为弱引用不会去回收常量池里头的对象。
例如
public static void main(String[] args) {
String name = "hepheastushao";
WeakReference weakRef = new WeakReference(name);
name = null;
System.gc();
System.out.println(weakRef .get());// 常量不会被回收
}
四、虚引用(使用情况极少,代码后补)
通过虚引用来跟踪对象什么时候会被回收,在对象要被回收之前需要做处理的话,就可以用到虚引用。
虚引用的使用类:PhantomReference类,必须和ReferenceQueue队列一同使用才可以。