了解Java中的弱引用WeakReference,以及GC回收机制.有助于在以后的工作和面试中获得加分.下面就来详细的说下java中的弱引用WeakReference.
在java中一个对象被GC回收需要满足两个条件: 1.没有任何引用指向他; 2.GC被运行.
例如:
Grill gril = new Gril();
gril = null;
将gril对象 手动置空,GC被运行的时候会自动回收了. 然而对于程序来说不可能每次都需要程序员进行手动置空,Java中,简单的对象,当调用它的方法完毕时,指向他的引用就会被从stack中popup ,所以GC被执行是可以自动回收.
当使用cache的时候,程序运行是一直需要cache的对象, 所以GC就无法回收这个对象, 进行无法回收cache中的object引用.渐渐的无法回收的reference越来越多.当这些object需要被回收时,就必须由程序员主动来进行回收了, 由于不符合java中GC回收的本质,便引入了弱引用WeakReference.
当一个对象仅仅被WeakReference指向, 而没有任何其他StrongReference指向的时候, 如果GC运行, 那么这个对象就会被回收. WeakReference的语法是:
Grill gril = new Gril();
WeakReference grilWeakReference = new WeakReference<>(gril);
当要获得WeakReference引用的object时, 首先需要判断它是否已经被回收:
grilWeakReference.get();//判断grilWeakReference指向的对象是否被回收, 返回值为空则被回收了
例如:
public static void main(String[] args){
Grill gril = new Gril();
WeakReference grilWeakReference = new WeakReference<>(gril);
while(true){
if(grilWeakReference.get()!= null){
System.out.println("gril对象还存在");
} else {
System.out.println("gril已经被回收");
}
}
}
上面代码运行结果是”gril已经被回收”且 gril 是一个strongReference,
grilWeakReference 指向的对象仍然被回收了. 这是因为java的编译器在发现进入while循环之后, gril已经没有被使用了, 所以进行了优化将其置空
public static void main(String[] args){
Grill gril = new Gril();
WeakReference grilWeakReference = new WeakReference<>(gril);
while(true){
System.out.println(gril);//控制台输出gril的toString()方法结果.
if(grilWeakReference.get()!= null){
System.out.println("gril对象还存在");
} else {
System.out.println("gril已经被回收");
}
}
}
上面代码运行结果是”gril对象还存在”, 因为还有一个gril.toString()方法strongReference在指向他.
WeakReference的一个特点是它何时被回收是不可确定的, 因为这是由GC运行的不确定性所确定的. 所以, 一般用WeakReference引用的对象是有价值被cache, 而且很容易被重新被构建, 且很消耗内存的对象.
还有一种是soft reference
SoftReference和WeakReference一样, 但被GC回收的时候需要多一个条件: 当系统内存不足时(GC是如何判定系统内存不足? 是否有参数可以配置这个threshold?), soft reference指向的object才会被回收. 正因为有这个特性, SoftReference比WeakReference更加适合做CacheObjects的reference. 因为它可以尽可能的retain cached objects, 减少重建他们所需的时间和消耗.