java 强引用,软引用,弱引用,虚引用
Java从JDK1.2版本开始,把对象的引用分为四种级别
强引用(StrongReference),软引用(SoftReference),弱引用(WeakReference),虚引用(PhantomReference)
StrongReference :
使用的大部分引用实际上都是强引用, 当内存空 间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,也不会靠随意回收具有强引用的对象.
like
String a = new String(“a”);
引用内容“a” 存放于堆中,变量 a 是“a”的强引用,存放于栈中
SoftReference:
如果一个对象只具有软引用,垃圾回收器进行回收时,如果内存空间不足则回收,如果内存空间充足则不回收。可配合ReferenctQueue使用,当对象被回收后“软引用”会被加入到ReferenceQueue中。
WeakReference:
如果一个对象只具有弱引用,垃圾回收器进行回收时,只要发现就回收。不管内存是否充足。可配合ReferenctQueue使用,当对象被回收后“弱引用”会被加入到ReferenceQueue中。
PhantomReference:
虚引用对象随时可能被回收,虚引用必须配合ReferenctQueue使用,当对象被回收前“虚引用”会被加入到ReferenceQueue中。
import java.lang.ref.*;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* Created by lixiaoqing
*/
public class ReferenceTest {
public static void main(String[] args) {
softReferenceTest();
weakReferenceTest();
phantomReferenceTest();
}
private static void softReferenceTest(){
System.out.println("SoftReferenceTest : \n");
String string = new String ("String Object");
SoftReference<String> stringSoftReference = new SoftReference<String>(string);
string = null;
System.out.println(stringSoftReference.get());
// 缺少内存占满条件,所以...
System.gc();
System.out.println(stringSoftReference.get());
System.out.println("\n------------------------------------------------------");
}
private static void weakReferenceTest(){
System.out.println("WeakReferenceTest : \n");
String string = new String("String Object");
ReferenceQueue referenceQueue = new ReferenceQueue();
WeakReference<String> stringWeakReference = new WeakReference<String>(string, referenceQueue);
string = null;
System.out.println("stringWeakReference get : " + stringWeakReference.get());
System.out.println("referenceQueue poll : " + referenceQueue.poll());
System.gc();
System.out.println("stringWeakReference get : " + stringWeakReference.get());
System.out.println("referenceQueue poll : " + referenceQueue.poll());
System.out.println("referenceQueue poll : " + referenceQueue.poll());
System.out.println("\n------------------------------------------------------");
}
static ReferenceQueue referenceQueue = new ReferenceQueue();
static Map<Reference, Integer> phantomMap = new HashMap<>();
private static void phantomReferenceTest(){
System.out.println("PhantomReferenceTest : \n");
Object object = new Object();
System.out.println(object.hashCode() +" 创建成功");
PhantomReference<Object> phantomReference = new PhantomReference<Object>(object, referenceQueue);
phantomMap.put(phantomReference, object.hashCode());
new Thread(runnable).start();
object = null;
System.gc();
}
// 独立线程进行监听弱可及对象回收
static Runnable runnable = new Runnable() {
@Override
public void run() {
Reference reference;
while((reference = referenceQueue.poll()) == null){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int objectHashCode = phantomMap.get(reference);
System.out.print(objectHashCode +" 被回收了");
}
};
private static void waitTime(long time){
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
控制台
SoftReferenceTest :
String Object
String Object
WeakReferenceTest :
stringWeakReference get : String Object
referenceQueue poll : null
stringWeakReference get : null
referenceQueue poll : java.lang.ref.WeakReference@3cd1a2f1
referenceQueue poll : null
PhantomReferenceTest :
789451787 创建成功
789451787 被回收了