Java--引用

  • 强引用
    创建一个对象,让一个引用变量指向该对象,该引用变量就是强引用,处于可达的状态,是不可能被垃圾回收期机制回收的,,如果一个对象没有被引用对象指向,可认为是可以被回收的。只要有引用变量指向,都不会回收。
	@Test
	public void test01() {
		Object obj1=new Object();
		Object obj2=obj1;
		obj1=null;
		//垃圾回收
		System.gc();
		//照常输出obj2指向的对象
		System.out.println(obj2);
	}

代码中创建了obj1 obj2引用变量,obj1指向null,执行垃圾回收,打印obj2的结果,发现依然是开始的对象,创建引用变量,然后指向分配的对象,为强引用,只要还有引用变量指向,就不会被垃圾回收器收集。

  • 软引用
    SoftReference
    如果内存够不会被回收,如果内存不够了,将会被回收。
    测试代码
	/**
	 * 软引用 
	 * 添加jvm参数 -Xms5m -Xmx5m -XX:+PrintGCDetails -XX:+PrintCommandLineFlags
	 */
	@Test
	public void test02() {
		Object obj1 = new Object();
		SoftReference<Object> softReference = new SoftReference<Object>(obj1);
		System.out.println(obj1);
		System.out.println(softReference.get());

		obj1 = null;
		try {
			// 分配30M的内存空间
			byte[] bytes = new byte[30 * 1024 * 1024];
		} finally {
		    //null
			System.out.println(obj1);
			//null
			System.out.println(softReference.get());
		}
	}

创建obj1应用变量,然后赋值给软应用,然后让obj1不指向new 的对象。分配超过堆内存空间的数组。打印软引用。
适合缓存很多数据,同时避免出现OOM。

  • 弱引用
    WeakReference
    不管内存够不够,下次发生GC都会被回收。
	@Test
	public void test03() {
		WeakReference<Object> softReference = new WeakReference<Object>(new Object());
		//java.lang.Object@65e2dbf3
		System.out.println(softReference.get());
		System.gc();
		//打印null,已经被回收了。
		System.out.println(softReference.get());
	}

使用案例WeakHashMap

	@Test
	public void test05() {
		WeakHashMap<Integer, String> map=new WeakHashMap<>();
		
		Integer key=new Integer(1);
		String value="WeakHashMap";
		
		map.put(key, value);
		//{1=WeakHashMap}
		System.out.println(map);
		
		key=null;
		//{1=WeakHashMap}
		System.out.println(map);
		
		System.gc();
		//{} 1
		System.out.println(map+" "+map.size());
	}

key指向的内存空间如果没有其他引用变量指向该处,那么指向gc的时候将会把该键值对回收。

  • 虚引用
    PhantomReference
    如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能会被垃圾回收器回收掉。

  • 引用队列

	@Test
	public void test07() throws InterruptedException {
		Object obj1=new Object();
		ReferenceQueue<Object> referenceQueue=new ReferenceQueue<>();
		PhantomReference<Object> phantomReference=new PhantomReference<Object>(obj1, 
				referenceQueue);
		//java.lang.Object@65e2dbf3
		System.out.println(obj1);
		//null
		System.out.println(phantomReference.get());
		//null
		System.out.println(referenceQueue.poll());
		
		obj1=null;
		System.out.println("-----------gc-------------");
		System.gc();
		Thread.sleep(2000);
		
		//null
		System.out.println(obj1);
		//null
		System.out.println(phantomReference.get());
		//true
		System.out.println(referenceQueue.poll()==phantomReference);
	}

引用在被回收之前会被被放到引用队列。 \color{#FF0000}{引用在被回收之前会被被放到引用队列。} 引用在被回收之前会被被放到引用队列。 如果队列中有数据,那么说明发生了gc回收,JVM允许我们在垃圾回收之前做我们想做的事情。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值