java中的4种引用类型简单了解

1.有关知识点英文

强引用 Strong reference
软引用 SoftReference
弱引用 WeakReference
虚引用(幽灵引用) PhantomReference

引用队列 ReferenceQueue

2.分析如下:

public class Z {
	public static void main(String[] args) {

		//强引用:创建一个对象,并把这个对象赋给一个变量,那么该变量持有对该对象实例的强引用
                //只要某个对象有强引用与之关联,JVM必定不会回收这个对象,即使在内存不足的情况下,JVM宁愿抛出OutOfMemory错误也不会回收这种对象
                //如果想中断强引用和某个对象之间的关联,可以将引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象
                /*new Z().fun1();
                    System.gc();*/
                /*new Z().fun2();*/
		
		//软引用:内存不足,则回收,足则不回收,常用于高速缓存,图片缓存,网页缓存。。。
		/*new Z().fun3();*/
		/*new Z().fun4();*/
		
		//弱引用:只要gc回收,就会被回收
		//弱引用能用来在回调函数中防止内存泄露,
		//因为回调函数往往是匿名内部类,隐式保存有对外部类的引用,
		//所以如果回调函数是在另一个线程里面被回调,而这时如果需要回收外部类,
		//那么就会内存泄露,因为匿名内部类保存有对外部类的强引用
		/*new Z().fun5();*/
		
		//虚引用:垃圾回收时回收,无法通过引用取到对象值。不影响对象的生命周期
		//必须和引用队列关联使用
		new Z().fun6();
        
	}

	//以下函数每次只在main函数里用一个进行测试
	
	public void fun1() {
        Object[] object = new Object[1000000000];
        System.gc(); //gc回收
        }//打印如下:即使抛出OutOfMemoryError异常,也不回收.
    //Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    //at com.example.liuyan.myapplication.Test.fun1(Test.java:17)
    //at com.example.liuyan.myapplication.Test.main(Test.java:10)
	
	public void fun2() {
		String string = "abc";
		System.gc();
		//string = null; 加上这句就会打印出null,证明中断了强引用
		System.out.println(string);
	}//可以看到,即使用了回收依然会打印abc
	
	public void fun3() { 
		String string = new String("abc");
		SoftReference<String> sf = new SoftReference<String>(string);
		string = null; //结束掉obj的强引用,不然sf会与强引用关联,在内存不足的时候也不能回收
		System.out.println("sf1 " + sf.get());
		System.out.println("string  " + string);
		System.gc(); //有时候(内存不足时)sf.get()会返回null
		System.out.println("sf2 " + sf.get());
	} //这时候sf是对obj的一个软引用,通过sf.get()方法可以取到这个对象,当然,当这个对象被标记为需要回收的对象时,则返回null
	//这里因为内存足够所以软引用有,sf没被回收.如果内存不足,则会被回收sf.get()为null
	//打印如下://sf1 abc
		//string  null
		//sf2 abc
	
	public void fun4() {
		String[] strings = new String[44624270];
		for (int i = 0; i < strings.length; i++) {
			strings[i] = "abcdefghijklmnopqrstuvwxyz";
		}
		SoftReference<String[]> sf = new SoftReference<String[]>(strings);
		strings = null;
		System.out.println("sf1 " + sf.get());
		System.out.println("string  " + strings);
		System.gc(); //有时候(内存不足时)sf.get()会返回null
		System.out.println("sf2 " + sf.get());
	} //这里因为内存不足,所以gc回收后,sf.get()为null
	
	public void fun5() {
		WeakReference<String> sr = new WeakReference<String>(new String("abc"));
        System.out.println(sr.get());
        System.gc();                //通知JVM的gc进行垃圾回收
        System.out.println(sr.get()); //不管内存足不足,都会被回收了为null
        System.out.println(sr.isEnqueued());//返回是否被垃圾回收器标记为即将回收的垃圾
	} //打印如下://abc
		//null
		//false
	
	public void fun6() {
		String string = new String("abc");
		ReferenceQueue<String> queue = new ReferenceQueue<String>();
		PhantomReference<String> pf = new PhantomReference<String>(string, queue);
		string=null;
		System.out.println(pf.get()); //永远返回null
		System.out.println(pf.isEnqueued()); //返回是否从内存中已经删除
		System.gc();
		System.out.println(pf.get()); //永远返回null
		System.out.println(pf.isEnqueued()); //返回是否从内存中已经删除//打印如下:null  false  null  true
	}
	
	
}

3.补充如下:

当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会把这个虚引用加入到与之 关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否被垃圾回收.

下图为引用资源图:https://www.cnblogs.com/huajiezh/p/5835618.html


一句话概括,就是弱中选强,为被多个对象引用时的引用类型.



  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值