java的四种引用方式,java中什么叫引用类型
00-1010前言强引用最终引用软引用弱引用弱引用幻象引用
00-1010今天,当我读代码时,看到一些涉及弱引用,的东西,我想编Java的四种引用类型。Java专门为引用类型定义了一个类引用,它是引用对象的抽象基类。
这个类定义了所有引用对象共有的操作。因为这个类与垃圾收集器密切相关,所以这个类不能被直接子类化。
Reference有四个子类,分别是强引用FinalReference、软引用SoftReference、弱引用weakReference和虚引用PhantomReference。
意味着这四个引用都是JVM中GC使用的,我们根本不需要写代码。
目录
对象obj=新对象();上面,我们创建了一个Object对象,并将其赋给obj,这是对new Object()的强引用。Java中的引用默认就是强引用。
强引用的特点是,只要有一个强引用,被引用的对象就不会被垃圾回收。只有当强引用不存在时,被引用的对象才会被垃圾回收。
写个demo吧,新建一个BeanA,重写finalize方法:
public class Beana { @ override protected void finalize(){ system . out . println( Clear the object out of memory );}}然后写一个测试方法,将强引用设置为null后,通知JVM垃圾回收。
public static void main(String[]args)抛出io exception { BeanA a=new BeanA();a=空;system . GC();//阻止finalize方法System.in.read()在gc线程结束后不被执行;}输出结果:从内存中清除该对象。
可以看出,强引用是不存在的,被引用的对象是可以垃圾回收的。
前言
软引用用于描述一些有用但不必要的引用。
SoftReference的实例存储Java对象的软引用,并且软引用的存在不影响垃圾收集线程对Java对象的收集。
意味着被引用的对象只有在内存不足时才会被回收,内存足够时不会被回收。
只要垃圾收集器不回收它,程序就可以使用该对象。与这个软引用无关(即软引用不留白),只与内存有关。
直接看demo:
public static void main(String[]args){ SoftReferencebyte[]soft=new soft reference(new byte[1024 * 1024 * 10]);system . out . println(soft . get());试试{ thread . sleep(500);} catch(interrupted exception e){ e . printstacktrace();} system . GC();//注释掉下面这句话://byte[]bytes=new byte[1024 * 1024 * 15]可以通过get()方法两次获得;system . out . println(soft . get());}
我们创建了一个SoftReference对象,它的变量名soft强引用这个SoftReference对象,这个SoftReference对象保存一个软引用,它引用一个10M数组。
当然这个10M数组也可以替换成自己新建的对象:
A A=new A();SoftReferenceA soft=新
SoftReference<>(a);这样的话SoftReference对象中保存的a就变成了软引用,如果内存足够的话,将a=null,GC后使用soft.get还是可以获取到该对象。
我们这里使用10M数组来测试,启动测试类设定VM内存20M,发现再新建一个15M数组后会将原来的10M数组给GC掉。
输出结果:
[B@2cfb4a64[B@2cfb4a64
[B@2cfb4a64null
总结一句话就是:创建强引用时内存不够就把软引用占的内存给回收掉。
总结一个词就是:欺软怕硬。
另外软引用非常适合缓存使用。
弱引用weakReference
弱引用和软引用很类似,不同的是弱引用引用的对象只要垃圾回收执行,就会被回收,而不管是否内存不足。
我demo没有设定vm:Xmx=20M,通知JVM进行垃圾回收后依然会将被引用对象回收掉。
public static void main(String[] args){ WeakReference<byte[]> soft = new WeakReference<>(new byte[1024*1024*10]); System.out.println(soft.get()); //通知JVM进行垃圾回收 System.gc(); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(soft.get()); }
输出结果:
[B@2cfb4a64null
虚引用PhantomReference
首先,虚引用是无法通过get方法来获取的。一个虚引用对象被回收时会被放在一个ReferenceQueue队列中,意思就是虚引用回收时会给出一个信号放在队列中。
ReferenceQueue<Object> rq = new ReferenceQueue<>(); Object obj = new Object(); PhantomReference<Object> phantomReference = new PhantomReference<>(obj,rq); obj = null; System.out.println("Reference: "+phantomReference.get()); System.gc(); Reference<Object> r = (Reference<Object>)rq.poll(); System.out.println("ReferenceQueue: "+r);
输出结果两个null。只有VM内存不足时才会回收这个虚引用,才会将其放在队列中,才能通过poll()获取到队列中的PhantomReference对象,而这个引用对象需要程序员自己进行特殊处理。
那问题来了,甭管G不GC我都拿不到它,那它有啥用?
其实它一般用来管理直接内存,我们的垃圾回收器是在JVM中管理内存的,如果我们从网络中下载一个文件保存在os的内存中,而 新版JVM不需要copy一份到jvm内存中,通过引用可以直接访问操作系统管理的内存,当我们回收这个虚引用时,则会在队列中放入这个引入对象,方便用来特殊处理。
到此这篇关于Java的引用类型常用的四种方法的文章就介绍到这了,更多相关Java引用类型内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。