zoukankan      html  css  js  c++  java
  • java WeakReference

    在Java 1.2中就引入了java.lang.ref这个包,WeakReference就属于这个包。WeakReference是干嘛的呢,一言弊之,它是和Java中的垃圾回收相关的。如果一个对象只有WeakReference引用它,那么这个对象就可能被垃圾回收器回收。
    
    在什么场合下应用WeakReference呢?
    
    有时我们会碰到一些不能继承的类,如final class, 或者通过Factory创建的对象,它对外只暴露一个接口,我们无法知道它的具体实现类,自然也无法继承它。假如我们要使用一个Widget类,因为某种 缘故,我们无法继承该类来加入某个功能。但是,我们必须将每个Widget对象和某个序列号关联,而Widget本身没有serial number这个属性,这时该怎么做呢?
    
    你也许已经想到,用HashMap!对,像这样:
    1.serialNumberMap.put(widget, widgetSerialNumber);
    
    这看起来工作的很好。但是,有个问题:当我们不再需要某个Widget的serial number信息,此时应该从HashMap中将这个Entry移除,如果我们忘记了怎么办?因为HashMap中持有对这个对象的引用,这个对象永远不 会被垃圾回收器回收,这就造成了内存泄漏!这意味着我们需要像没有垃圾回收功能的语言一样,手动管理内存!但是我们用的是Java.....
    
    另一个很常见的问题是缓存。如果使用强引用,那么我们缓存的对象就会一直滞留在内存中,不会被回收,除非我们手动的将其从缓存中移除。此外,这还需要我们决定何时从缓存中移除对象,又一个手动管理内存的问题!
    
    此时,WeakReference就显示出它的价值了。如何创建一个WeakReference呢?很简单:
    1.WeakReference<widget> weakWidget = newWeakReference<widget>(widget);
    2.Widget w = weakWidget.get();
    
    要注意的是,当调用weakReference.get()可能返回null(意味着指向的对象已经被回收)。其实,对于Widget serial number这个问题,最简单的方法是使用WeakHashMap,它的使用和普通的HashMap完全一样,不同点在于,WeakHashMap的key被实现为一种WeakReference(注意,是key而不是value),当key对象被回收后,WeakHashMap会自动将对应的entry移除。更精确的说,对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的回收。
    
    Java中有四种类型的引用,按照强弱关系依次为:Strong Reference>Soft Reference>WeakReference> Phantom Reference。
    
    其中,我们平常用的就是Strong Reference,而Phantom Reference很少用到,因此这里不去研究了,那么什么是Soft Reference呢?
    
    Soft Reference和weak reference的区别是:一旦gc发现对象是weak reference可达就会把它放到ReferenceQueue中,然后等下次gc时回收它;当对象是Soft reference可达时,gc可能会向操作系统申请更多内存,而不是直接回收它,当实在没辙了才回收它。像cache系统,最适合用Soft reference。让gc来替我们决定什么时候回收对象以及回收哪些对象。
    在Java里, 当一个对象o被创建时, 它被放在Heap里. 当GC运行的时候, 如果发现没有任何引用指向o, o就会被回收以腾出内存空间. 
    或者换句话说, 一个对象被回收, 必须满足两个条件:
    (1)没有任何引用指向它 
    (2)GC被运行.

     创建一个弱引用

     1 public class Test {
     2 
     3     public static void main(String[] args) throws  Exception {
     4         Car car=new Car("宾利","银白色");
     5         WeakReference<Car> weakCar=new WeakReference<Car>(car);
     6         int i=0;
     7         while (true){
     8             Thread.sleep(5000L);
     9             if(weakCar.get()!=null){
    10                 i++;
    11                 System.out.println(car.getRed()+car.getName()+i+"次");
    12 
    13             }else{
    14                 System.out.println("对象为空,已经被gc回收了!"+weakCar.get());
    15                 break;
    16             }
    17             Thread.sleep(5000L);
    18         }
    19 
    20     }
    21 
    22     static class Car{
    23         private String name;
    24 
    25         private String red;
    26 
    27         public Car(String name,String red){
    28             this.name=name;
    29             this.red=red;
    30         }
    31 
    32         public String getName() {
    33             return name;
    34         }
    35 
    36         public void setName(String name) {
    37             this.name = name;
    38         }
    39 
    40         public String getRed() {
    41             return red;
    42         }
    43 
    44         public void setRed(String red) {
    45             this.red = red;
    46         }
    47     }
    48 }

    弱引用这种使用比较多的情况是运用在缓存系统中.

    参考:http://blog.sina.com.cn/s/blog_4a4f9fb50100u908.html

    这篇文章的例子很详细..

    O(∩_∩)O哈哈~

  • 相关阅读:
    CUDA中修饰符的解释
    [C] zintrin.h : 智能引入intrinsic函数。支持VC、GCC,兼容Windows、Linux、Mac OS X
    GPU优化方法[转]
    Angularjs实例2
    Angularjs实例1
    Services 在多个 controller 中共享数据。
    自定义AngularJS中的services服务
    AngularJS web应用程序
    AngularJS 表单
    在文件中的AngularJS模块
  • 原文地址:https://www.cnblogs.com/huzi007/p/5175388.html
Copyright © 2011-2022 走看看