强引用-如果对象还可达,发生OOM也不回收
Java大部分对象都是强引用的,对于强引用的对象,超过其作用域或者显示的复为null,则可能在垃圾回收时将其回收掉。
软引用(SoftReference)-内存不足时回收
在即将发生OOM时,进行回收
多用于缓存
public class SoftReferenceTest {
public static void main(String[] args) {
String str=new String("str");
SoftReference softReference = new SoftReference(str);
System.out.println(str);
str=null;
System.out.println(str);
System.out.println(softReference.get());
}
}
输出
str
null
str
上面强引用str,已经设为不可达,但是软引用还是可以获取到对象的。
弱引用(WeakReference)—发现就回收
弱引用的对象只能存活到下一次垃圾回收之前
类似软引用,都适合做缓存使用
见ThreadLoacl的使用,见WeakHashMap
虚引用(PhantomReference)—对象回收跟踪
虚引用和没有引用一样,随时都可能被回收
虚引用用于垃圾回收的通知感知
虚引用的get方法获取的都是null
public class PhantomReferenceTest {
private static String abc = new String("abc0");
static boolean isRun = true;
public static void main(String[] args) throws InterruptedException {
ReferenceQueue<String> referenceQueue = new ReferenceQueue<String>();
new Thread() {
@Override
public void run() {
while (isRun) {
PhantomReference obj = (PhantomReference) referenceQueue.poll();
if (obj != null) {
System.out.println("full gc " + obj);
Field rereferent = null;
try {
rereferent = Reference.class
.getDeclaredField("referent");
rereferent.setAccessible(true);
Object result = rereferent.get(obj);
System.out.println("full gc " + result);
isRun = false;
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}.start();
PhantomReference<String> abcWeakRef = new PhantomReference<String>(abc, referenceQueue);
abc = null;
Thread.currentThread().sleep(3000);
System.gc();
Thread.currentThread().sleep(3000);
}
}
上述例子是一个根据虚引用感知被垃圾回收的例子。
通过反射获取父类的reference字段,获取引用的值,真正不推荐这样用,了解就好,基本不会使用。
软引用、弱引用、虚引用都可以传一个ReferenceQueue用来监控实现Reference的引用对象的垃圾回收。
可以在外部对这个queue进行监控。即如果有对象即将被回收,那么相应的reference对象就会被放到这个queue里。就可以感知到这个类要被回收了。
网友评论