Java-软引用、弱引用、虚引用、WeakHashMap
SoftReference、WeakReference、PhantomReference、ReferenceQueue
1.SoftReference:对象只有软引用时,若内存空间充足时,不GC,内存空间紧张时,回收该对象
2.WeakReference:对象只有弱引用时,当垃圾收集器扫描时,无论内存空间是否紧张都回收
3.PhantomReference:
4.ReferenceQueue:作为一个Java对象,SoftReference对象除了具有保存软引用的特殊性之外,也具有Java对象的一般性。所以,当软可及及象被回收之后,虽然这个SoftReference对象的get()方法返回null,但这个SoftReference对象已经不再具有存在的价值,需要一个适当的清除机制,避免大量SoftReference对象带来的内存泄漏。在java.lang.ref包里还提供了ReferenceQueue。如果在创建SoftReference对象的时候,使用了一个ReferenceQueue对象作为参数提供给SoftReference的构造方法,如:
ReferenceQueue queue = new ReferenceQueue();
SoftReference ref=new SoftReference(aMyObject, queue)
那么当这个SoftReference所软引用的aMyOhject被垃圾收集器回收的同时,ref所强引用 的SoftReference对象被列入ReferenceQueue。也就是说,ReferenceQueue中保存的对象是Reference对象,而且是已经失去了它所软引用的对象的Reference对象。另外从ReferenceQueue这个名字也可以看出,它是一个队列,当我们调用它的poll()方法的时候,如果这个队列中不是空队列,那么将返回队列前面的那个Reference对象。
下面的例子演示了垃圾收集弱引用,同时被收集的弱引用被加入ReferenceQueue中:
public class TestReference {
private static ReferenceQueue< VeryBig > rq = new ReferenceQueue <VeryBig > ();
public static void main (String [] args ) {
WeakReference <VeryBig > sr = new WeakReference (new VeryBig ("" +1 ) , rq );
System .gc () ;
Reference <VeryBig > ref = ( Reference <VeryBig >) rq .poll ();
if ( ref != null ) {
System .out . println( ref .get ()) ;
}
}
}
class VeryBig {
private static final int SIZE = 1000000 ;
private long [] la = new long [ SIZE] ;
private String id ;
VeryBig (String id) {
this. id = id ;
}
public String toString() {
return id;
} ;
protected void finalize() {
System .out . println( "Finalizing" + id );
}
}
输出:
Finalizing1
或
Finalizing1
null
WeakHashMap:这种hashmap中存放了,键对象的弱引用,弱键对象只被该弱引用引用,垃圾收集时将被回收内存:
实例(键对象中id为3的倍数的对象被数组中的强引用引用,所有垃圾收集时不会被回收内存):
class Element {
private String ident;
public Element (String id) {
ident = id ;
}
public String toString () {
return ident;
}
public int hashCode () {
return ident. hashCode ();
}
public boolean equals ( Object obj ) {
return obj instanceof Element && ident. equals((( Element ) obj ). ident );
}
protected void finalize (){
System .out . println( "Finalizing "+ getClass() . getSimpleName() + " "+ ident );
}
}
class Key extends Element {
public Key (String id){
super (id ) ;
}
}
class Value extends Element {
public Value ( String id ){
super (id ) ;
}
}
public class TestReference {
public static void main( String [] args ){
int size =1000 ;
Key [] keys= new Key[ size ];
WeakHashMap map =new WeakHashMap () ;
for (int i = 0; i < size ; i++ ){
Key k =new Key ( Integer. toString (i )) ;
Value v =new Value ( Integer. toString (i )) ;
if (i % 3== 0 )
keys [ i] = k;
map. put (k , v) ;
}
System .gc () ;
}
}