• Java四种引用


    JDK1.2之前,Java中引用(reference)的定义:如果reference类型的数据中存储的数值代表的是另外一块内存的起始地址,那么这块内存就是一个引用。这样的概念不足以应对这样的情况:对于一些可有可无的对象,当内存空间足够时,则将对象保存在内存中,不回收;如果内存在垃圾回收后还是不足,就可以回收这这些对象。JDK1.2之后的版本对引用做了扩充:将引用分为四类:
    1.强引用(Strong Reference);
    2.软引用(Soft Reference);
    3.弱引用(Weak Reference);
    4.虚引用(Phantom Reference).
    这4种级别由高到低依次为:强引用、软引用、弱引用和虚引用。

    **强引用是最常见的引用形式,例如用new关键字创建的对象,例如:A为一个类,A a = new A();这类的引用就是一个强引用。只要强引用还存在,永远不回收。

    public class Strong_Reference_Test {
    	public void infor()
    	{
    		System.out.println("I am OK!");
    	}
    	@SuppressWarnings("unused")
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		Strong_Reference_Test strong_reference  = new Strong_Reference_Test();
    		System.gc();
    		if(strong_reference==null)
    		{
    			System.out.println("被回收!");
    		}
    		strong_reference.infor();
    	}
    
    }
    虽然执行了gc();但是并未回收。

    **软引用,用来描述一些还有用但是非必须的对象引用。对于软引用引用的对象,在系统将要发生内存溢出之前,将会把这些对象列入可回收范围之内进行二次回收。回收之后还是内存不够,才会抛出内存溢出异常。如果未被回收,那么程序可以继续使用。SoftReference类实现软引用。软引用可用来实现内存敏感的高速缓存。软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。

    -verbose:gc -Xms2M -Xmx2M ;利用参数将执行的堆内存设置为2M。

    import java.lang.ref.SoftReference;
    class A
    {
    	public int i;
        public A(int i)
        {	
        	this.i = i;
        }
    }
    public class Reference_Test {
    	@SuppressWarnings("unchecked")
    	public static void main(String args[])
    	{
    		/*SoftReference<A> []s = new SoftReference[50000];
    		for(int i = 0; i< s.length ;i++)
    		{	
    			s[i] = new SoftReference<A>(new A(i));
    		}
    		//System.out.println(s[4].get());
    		System.gc();
    		int count = 0;
    		for(int i = 0; i< s.length ;i++)
    		{
    			if(s[i].get()!=null)
    				count++;
    		}
    		 System.out.println("未被回收数量:"+count);
    		 
    		*/
    		int count = 0;
    		SoftReference<A> []s1 = new SoftReference[10000];
    		for(int i = 0; i< s1.length ;i++)
    		{	
    			s1[i] = new SoftReference<A>(new A(i));
    		}
    		System.gc();
    		
    		for(int i = 0; i< s1.length ;i++)
    		{
    			if(s1[i].get()!=null)
    				count++;
    		}
    		 System.out.println("未被回收数量:"+count);
    	}
    }

    注释的代码因为内存不足,会回收软引用,结果count<50000,大约在30000左右。未注释的代码因为内存充足,并不回收,count=10000。

    **弱引用也是描述非必须对象的,强度比软引用更弱,被弱引用引用的对象只能生存到下一次回收进行之前。无论当前内存是否足够,都会被回收。WeakReference类实现软引用。

    import java.lang.ref.WeakReference;
    class A
    {
    	public int i;
        public A(int i)
        {	
        	this.i = i;
        }
    }
    public class Reference_Test {
    	@SuppressWarnings("unchecked")
    	public static void main(String args[])
    	{
    		int count = 0;
    		WeakReference<A> []s1 = new WeakReference[10000];//内存足够
    		for(int i = 0; i< s1.length ;i++)
    		{	
    			s1[i] = new WeakReference<A>(new A(i));
    		}
    		System.gc();
    		
    		for(int i = 0; i< s1.length ;i++)
    		{
    			if(s1[i].get()!=null)
    				count++;
    		}
    		 System.out.println("未被回收数量:"+count);
    	}
    }
    虽然内存充足但是依然会回收,count=0。

    **虚引用是最弱的引用形式。也叫幽灵引用或幻影引用。无法通过一个虚引用来取得这个引用关联的实例对象。虚引用存在的唯一目的是希望在这个被引用的对象被回收前,收到一个系统通知。PhantomReference类实现虚引用。



  • 相关阅读:
    图-拓扑排序
    图-最短路径-Dijkstra及其变种
    【链表问题】打卡7:将单向链表按某值划分成左边小,中间相等,右边大的形式
    【链表问题】打卡5:环形单链表约瑟夫问题
    【链表问题】打卡6:三种方法带你优雅判断回文链表
    【链表问题】打卡4:如何优雅着反转单链表
    【链表问题】打卡3:删除单链表的中间节点
    【链表问题】打卡2:删除单链表的第 K个节点
    史上最全面试题汇总,没有之一,不接受反驳
    一些可以让你装逼的算法技巧总结
  • 原文地址:https://www.cnblogs.com/sunp823/p/5601437.html
Copyright © 2020-2023  润新知