zoukankan      html  css  js  c++  java
  • 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 () ;
      }
    }
    
  • 相关阅读:
    性能调优之网络速度检测
    通过脚本自动下载Esri会议材料
    移动目标在三维GIS中的实现方法
    java生成CSV文件
    java 提取(解压)zip文件中特定后缀的文件并保存到指定目录
    java 提取(解压)rar文件中特定后缀的文件并保存到指定目录
    spring boot 使用 POI 读取Excel文件
    spring boot jpa 使用<S extends T> List<S> findAll(Example<S> example)查询数据
    一个MySQL中两表联合update的例子(并带有group by分组)
    Java8 使用 stream().filter()过滤List对象(查找符合条件的对象集合)
  • 原文地址:https://www.cnblogs.com/gatsbydhn/p/5323392.html
Copyright © 2011-2022 走看看