WeakReference and WeakHashMap

时间:2021-10-13 08:57:05

弱引用通过WeakReference类实现,弱引用和软引用很像,但弱引用的引用级别更低。对于只有弱引用的对象而言,当系统垃圾回收机制运行时,不管系统北村是否足够,总会回收该对象所占用的内存。当然,并不是说当一个对象只有弱引用时,它就会立即被回收-正如那些失去引用的对象一样,必须等到系统垃圾回收机制运行时才会被回收。

import java.lang.ref.SoftReference;

import java.lang.ref.WeakReference;

public class WeakReferenceTest {

public static void main(String[] args){

Stringstr = newString("Java");

Stringstr1 = newString("Java");

SoftReference<String>sr = newSoftReference<String>(str1);

WeakReference<String>wr = newWeakReference<String>(str);

str= null;

str1= null;

System.out.println(sr.get());

System.out.println(wr.get());

System.gc();

System.runFinalization();

System.out.println(sr.get());

System.out.println(wr.get());

}

}

Output:

Java

Java

Java

null

不要使用String str = “Java”;这样就看不到运行效果,因为采用这样定义的字符串系统会缓存这个字符串直接量(会使用强引用来引用它),系统不会回收被缓存的字符串常量。

弱引用具有很大的不确定性,因为每次垃圾回收机制执行时都会回收弱引用的对象,而垃圾回收机制的运行又不受程序员的控制,因此程序获取弱引用所引用的Java对象时必须小心空指针异常-通过弱引用所获取的Java对象可能是null.

由于垃圾回收的不确定性,当程序希望从弱引用中取出被引用对象时,可能这个被引用对象已经被释放了。如果程序需要使用那个被引用的对象,则必须重新创建新对象。

public class WeakReferenceTest {

public static void main(String[] args){

Stringstr = newString("Java");

Stringstr1 = newString("Java");

SoftReference<String>sr = newSoftReference<String>(str1);

WeakReference<String>wr = newWeakReference<String>(str);

str= null;

str1= null;

System.out.println(sr.get());

System.out.println(wr.get());

System.gc();

System.runFinalization();

if(wr.get() == null){

str= new String("Java");

wr= newWeakReference<String>(str);

System.out.println(wr.get());

}

System.out.println(sr.get());

System.out.println(wr.get());

}

}

Output:

Java

Java

Java

Java

Java

与weakReference功能类似的还有WeakHashMap,当程序有大量的java对象需要使用弱引用来引用时,可以考虑使用weakHashMap来保存它们。

import java.util.WeakHashMap;

class CrazyKey{

String name;

public CrazyKey(String name){

this.name =name;

}

public inthashCode(){

return name.hashCode();

}

public boolean equals(Object obj){

if(obj==this){

returntrue;

}

if(obj!=null && obj.getClass() == CrazyKey.class){

returnname.equals(((CrazyKey)obj).name);

}

returnfalse;

}

public String toString(){

return "CrazyKey[name=" + name +"]";

}

}

public class WeakHashMapTest {

public static void main(String[] args)throws InterruptedException{

WeakHashMap<CrazyKey,String>map = newWeakHashMap<CrazyKey,String>();

for(int i=0;i<10;i++){

map.put(new CrazyKey(i+1+""),"value"+(i+11));

}

System.out.println(map);

System.out.println(map.get(new CrazyKey("2")));

System.gc();

Thread.sleep(50);

System.out.println(map);

System.out.println(map.get(new CrazyKey("2")));

}

}

Output:

{CrazyKey[name=8]=value18,CrazyKey[name=9]=value19, CrazyKey[name=4]=value14, CrazyKey[name=5]=value15,CrazyKey[name=6]=value16, CrazyKey[name=7]=value17, CrazyKey[name=10]=value20,CrazyKey[name=1]=value11, CrazyKey[name=2]=value12, CrazyKey[name=3]=value13}

value12

{}

null

在垃圾回收机制运行之前,WeakHashMap的功能与普通HashMap并没有太大的区别,它们的功能相似。但一旦垃圾回收机制被执行,WeakHashMap中所有key-value就都会被清空,除非某些Key还有强引用在引用它们。