Java四种引用包括强引用,软引用,弱引用,虚引用

Java四种引用包括强引用,软引用,弱引用,虚引用。

先上引用的两个实体类

/**
 * 实体列A
 */
static class People{
    String name="A";
    int age=12;
    String sex="男";
}
/**
 * 实体列B
 */
static class Student{
    String name="B";
    int age=12;
    String sex="男";
}

强引用(StrongReference)

强引用,顾名思义,作用比较强,他强任他强,老子就是寸步不让.只要有这个引用在,当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不靠随意回收具有强引用的对象来解决内存不足的问题。

/**
 * 强引用
 */
public  static void strongReference(){
    People A=new People();
    Student B=new Student();
    new Thread(() -> {
        try {
            Thread.sleep(1000);
            A.name.equals(B.name);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }).run();
}

如上图例子有两个实体类,主线程建立两个实体类.然后通过equals方法,A持有了B的引用,假设在没有开子线程的情况下,在主线程中A引用B 然后由于都是方法内的局部变量,那么方法执行结束,该方法退栈,引用不存在,创建的两个实体类都被释放,当在方法中启动子线程后,由于延时,A 一直对B 进行的引用那么只有在线程执行完成后才能释放引用资源.像Android常说的Handler使用不当引起的内存泄露无外乎就是这么个情况,Handler持有Activity的引用,子线程中消息又对handler持有引用,当Activity关闭的时候,由于对Activity持有引用,导致Activity不能及时释放从而导致内存泄露

软引用(SoftReference)

软引用,就是欺软怕硬呗,如果一个对象只具有软引用,则内存空间足够,gc的时候并不会回收它;如果内存空间不足了,gc的时候说兄弟没地方了把你收了,然后就收了。只要垃圾回收器没有回收它,该对象就可以被程序使用。

/**
 * 软引用
 */
public static void softReference() {
    People A = new People();
    SoftReference<People> sf = new SoftReference<People>(A);
    List<byte[]> bytes = new ArrayList<>();
    while (Runtime.getRuntime().freeMemory()>64) {
        byte[] b = new byte[64];
        bytes.add(b);
        System.out.println("循环内:"+Runtime.getRuntime().freeMemory());
    }
    System.out.println("循环外:"+Runtime.getRuntime().freeMemory());
    People people = sf.get();
    System.out.println(people==null?"null":people.name);
    long freeMem=Runtime.getRuntime().freeMemory();

}

输出结果如下:

image

在内存严重不足马上要堆溢出的情况下,进行了gc处理 ,这个时候软引用中的对象依然别清空.
软引用可以和一个引用队列(ReferenceQueue)联合使用(和虚引用类似),如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。

弱引用(WeakReference)

为啥叫弱引用,顾名思义真的弱,真的怂,只具有弱引用的对象拥有更短暂的生命周期。只要gc立马就怂,然后牺牲小我,拯救他人.

/**
 * 弱引用
 */
public static void weakReference() {
    People A=new People();
    WeakReference<People> wf1 = new WeakReference<People>(A);
    WeakReference<People> wf2 = new WeakReference<People>(new People());
    A=null;//只是在弱引用的情况下  才会被回收
    System.gc();
    System.out.println(sf1.get());
    System.out.println(sf2.get());
}

如上面方法所示,wf1是传入了A,但是由于只具有弱引用的对象才会被回收,
People A=new People()这是强引用,如果不把A的引用去掉并不会回收当前对象.wf2直接传入一对象立马就回收掉

虚引用

“虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。虚引用主要用来跟踪对象被垃圾回收器回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中。

 /**
 * 虚引用
 */
public static void phantomReference() {
    People A=new People();
    ReferenceQueue<People> queue = new ReferenceQueue<>();
    PhantomReference<People> pf=new PhantomReference<>(A,queue);
    People people = pf.get();
    System.out.println(people==null);
}

输出结果为true

其实不光虚引用能判断对象是否回收,软引用和弱引用一样也可以不过必须联合ReferenceQueue来进行判断.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值