JAVA四种引用类型

JAVA四种引用类型

每种编程语言都有自己操作内存中元素的方式,例如在 C 和 C++ 里是通过指针,而在 Java 中则是通过“引用”。
在 Java 中一切都被视为了对象,但是我们操作的标识符实际上是对象的一个引用(reference)。

	//创建一个引用,引用可以独立存在,并不一定需要与一个对象关联
	String s;

通过将这个叫“引用”的标识符指向某个对象,之后便可以通过这个引用来实现操作对象了。

	String s = "hello world";
	System.out.println(s);

Java 中的垃圾回收机制在判断是否回收某个对象的时候,都需要依据“引用”这个概念
在 JDK.1.2 之后,Java 对引用的概念进行了扩充,将引用分为了:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)4 种,这 4 种引用的强度依次减弱。

强引用(Strong Reference)

把一个对象赋给一个引用变量,这个引用变量就是一个强引用。
Java中默认声明的就是强引用,比如:

	//只要strongReference 还指向Object对象,Object对象就不会被回收
	Object strongReference = new Object(); 

当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制回收的,即使内存不足时,JVM也会直接抛出 OutOfMemoryError,不会去回收。
因此强引用是造成 Java 内存泄漏的主要原因之一:
配置参数 -Xms2M -Xmx3M,将 JVM 的初始内存设为2M,最大可用内存为 3M,然后连续创建了 10 个大小为 1M 的字节数组,循环遍历将这些对象打印出来:

	/*强引用*/
    List<Object> list = new ArrayList<>();
	//创建10个1M的强引用字节数组
    for(int i = 0; i < 10; i++) {
        byte[] buff = new byte[1024 * 1024];
        list.add(buff);
    }

    //主动通知垃圾回收
    System.gc();

    for(Object obj : list) {
        System.out.println(obj);
    }

输出结果:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

如果想中断强引用与对象之间的联系,可以显示的将强引用赋值为null,这样一来,JVM就可以适时的回收对象了:

	strong = null;//显示的将强引用赋值为null

软引用(Soft Reference)

软引用需要用 SoftReference 类来实现
软引用是用来描述一些非必需但仍有用的对象。对于只有软引用的对象来说,当系统内存足够时它不会被回收,当系统内存空间不足时它会被回收。
配置参数 -Xms2M -Xmx3M,将 JVM 的初始内存设为2M,最大可用内存为 3M,然后连续创建了 10 个大小为 1M 的字节数组,并赋值给了软引用,循环遍历将这些对象打印出来:

   	List<SoftReference> list = new ArrayList<>();
    //创建10个1M的软引用字节数组
    for(int i = 0; i < 10; i++) {
        byte[] buff = new byte[1024 * 1024];
        list.add(new SoftReference<>(buff));
    }
	//遍历输出软引用的对象(注意要使用SoftReference的get方法)
    for(SoftReference softReference : list) {
        System.out.println(softReference.get());
    }

输出结果:

null
null
null
null
null
null
null
null
null
[B@4554617c

无论循环创建多少个软引用对象,打印结果总是只有最后一个对象被保留,其他的softReference全都被置空回收了。
这就说明了在内存不足的情况下,软引用将会被自动回收。
软引用通常用在对内存敏感的程序中,一般被用来实现缓存技术,比如网页缓存,图片缓存等。

弱引用(Weak Reference)

弱引用需要用 WeakReference 类来实现
它比软引用的生存期更短,对于只有弱引用的对象来说,只要垃圾回收机制一运行,不管 JVM 的内存空间是否足够,总会回收该对象占用的内存。
连续创建 5 个字节数组,并赋值给了弱引用,循环遍历将这些对象打印出来:

	/*弱引用*/
    List<WeakReference> list = new ArrayList<>();
    //创建5个弱引用字节数组
    for(int i = 0; i < 5; i++) {
        byte[] buff = new byte[1];
        list.add(new WeakReference<>(buff));
    }

    System.out.println("回收前:");
    for(WeakReference WeakReference : list) {
        System.out.println(WeakReference.get());
    }

    //主动通知垃圾回收
    System.gc();

    System.out.println("回收后:");
    for(WeakReference WeakReference : list) {
        System.out.println(WeakReference.get());
    }

输出结果:

回收前:
[B@4554617c
[B@74a14482
[B@1540e19d
[B@677327b6
[B@14ae5a5
回收后:
null
null
null
null
null

虚引用(Phantom Reference)

虚引用需要 PhantomReference 类来实现,它不能单独使用,必须和引用队列联合使用。
虚引用的主要作用是跟踪对象被垃圾回收的状态。
详见你不可不知的Java引用类型之——虚引用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值