码迷,mamicode.com
首页 > 其他好文 > 详细

4中引用(强,软,弱,虚)侧重弱引用

时间:2018-01-19 11:52:44      阅读:135      评论:0      收藏:0      [点我收藏+]

标签:适合   程序员   been   cte   soft   不可   string   url   网页缓存   

1,强引用,对象有强引用与之关联,即使在内存不足,抛出OutOfMemory错误也不会回收这种对象

2,软引用是用来描述一些有用但并不是必需的对象,java.lang.ref.SoftReference类来表示。
   对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象。可以很好地用来解决OOM的问题,适合用来实现缓存:比如网页缓存、图片缓存等。
   软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被JVM回收,这个软引用就会被加入到与之关联的引用队列中。

3,弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。
在java中,用java.lang.ref.WeakReference类来表示。 弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被JVM回收,就会被加入到与之关联的引用队列中。
4,虚引用和前面的软引用、弱引用不同,它并不影响对象的生命周期。在java中用java.lang.ref.PhantomReference类表示。 如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。 注意的是,虚引用必须和引用队列关联使用,当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会把这个虚引用加入到与之 关联的引用队列中。 弱引用和虚引用的区别是:虚引用总是存在的,只是看存在地方的。而若引用如果没有队列与关联,那么垃圾回收就会没了。如何有关联队列那么两者就一样了。

说说WeakReference弱引用

Java弱引用(WeakReference)的理解与使用

侧重说下弱引用:因为ThreadLocal用到了弱引用,而线程局部变量被广泛的应用在各种框架中。

了解如何定义和使用:

public class Car
{
    private double     price;
    private String    color;
    
    public Car(double price, String color)
    {
        this.price = price;
        this.color = color;
    }
public class WeakReferenceCar extends WeakReference<Car>
{
    public WeakReferenceCar(Car car)
    {
        super(car);
    }
}
Car car = new Car(2000.0, "red");
WeakReferenceCar wrc = new WeakReferenceCar(car);

当gc执行:WeakReferenceCar关联的对象Car被回收掉了。

值得注意的是car本身是有强引用的(xxx=new xxx()):

public static void main(String[] args) {
        
        Car car = new Car(22000,"silver");
        WeakReference<Car> weakCar = new WeakReference<Car>(car);        
        int i=0;        
        while(true){
            if(weakCar.get()!=null){
                i++;
                System.out.println("Object is alive for "+i+" loops - "+weakCar);
            }else{
                System.out.println("Object has been collected.");
                break;
            }
        }

 即使有 car 引用指向对象, 且 car 是一个strong reference, weakCar指向的对象仍然被回收了.

这是因为java的编译器在发现进入while循环之后, car 已经没有被使用了。

而如果后面有使用是不会被回收的比如下面:

        Car car = new Car(22000,"silver");
        WeakReference<Car> weakCar = new WeakReference<Car>(car);        
        int i=0;        
        while(true){
            System.out.println("here is the strong reference ‘car‘ "+car);
            if(weakCar.get()!=null){
                i++;
                System.out.println("Object is alive for "+i+" loops - "+weakCar);
            }else{
                System.out.println("Object has been collected.");
                break;
            }
        }

总结:

1,一个变量(该变量是局部变量)是否被回收,看方法是否执行完,一般都被回收的。
   但是如果赋值给了其他全局变量,那么是不会被回收的。

2,是否是强引用,一般是不会被回收,但是如果后面没有使用,也是会被回收的。

3,是否是弱引用,一般gc执行就会被回收,
但是如果有强引用关联,那么是不会被回收的, 但是出现第2点的情况,也就是后面不被使用了,也是会被回收的
(其实有强引用关联也就当作强引用的情况在处理了)

补充:对于强引用是否需要手动置空?以便让gc回收。

Object c = new Car();
c=null;

其实是不需要的,手动置空对象对于程序员来说, 是一件繁琐且违背自动回收的理念的.  

因为在java中, 对于简单对象, 当调用它的方法执行完毕后, 指向它的引用会被从stack中popup, 所以他就能在下一次GC执行时被回收了

 

最后一个问题:缓存用哪个引用?

很多人觉得用软引用更好,内存不够再回收。

个人觉得不可以:

据说内存不够时候,清理过程中程序会被挂起,这样很不友好。

而一般启动清理机制,应该是内存使用到达一定程度(应该是可以设置的),运行中的程序还是可以继续执行。

 

4中引用(强,软,弱,虚)侧重弱引用

标签:适合   程序员   been   cte   soft   不可   string   url   网页缓存   

原文地址:https://www.cnblogs.com/straybirds/p/8314115.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!