Java引用

在Java中有引用对象, 引用对象又分为强软弱虚四种

强引用

首先是强引用, 也就是普通引用:只要有一个引用指向了对象, java垃圾回收器就不会回收这个对象, 这就是普通引用(强引用), 当一个对象没有引用指向时就会被回收.

import java.io.IOException;

public class test01 {
    public static void main(String[] args) throws IOException {
        M m = new M();
//        m = null;
        System.gc();
        System.in.read();
    }
}
class M {
    @Override
    protected void finalize() throws Throwable{
        System.out.println("finalize");
        //当这个对象打印finalize时说明这个对象被回收了
        //正常情况下是不需要也不能重写这个回收函数
    }

}

代码的结果是永远不停止, 如果把m = null, 那么M对象将会被回收, 回收机制

软引用

引用m指向一个软引用对象, 软引用对象又指向一个10M的数组

在这里插入图片描述

import java.lang.ref.SoftReference;

public class test02 {
    public static void main(String[] args) {
        SoftReference<byte[]> m = new SoftReference<>(new byte[1024*1024*10]);//软引用 软引用对象里面有一个对象指向了一个10M的字节数组
        //m = null;
        System.out.println(m.get());
        System.gc();
        try {
            Thread.sleep(500);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println(m.get());
        //再分配一个数组, heap将装不下,这时系统会垃圾回收,先回收一次,如果不够,会把软引用干掉
        byte[] b = new byte[1024*1024*15];
        System.out.println(m.get());
    }
}

假定内存大小为20M, 为m分配了10M大小的空间, 又重新创建一个字节数组, 大小为15M, 这时m的内存就会被垃圾回收干掉, 因为内存不够用.
在这里插入图片描述
用途: 缓存

弱引用

在这里插入图片描述

import java.lang.ref.WeakReference;

public class test03 {
    public static void main(String[] args) {
        //弱引用碰到gc就会回收
        WeakReference<M> m = new WeakReference<>(new M());
        System.out.println(m.get());
        System.gc();
        System.out.println(m.get());
    }
}

m引用指向一个弱引用对象, 弱引用对象(弱弱地)指向M对象, 如果一个强引用指向这个M, 当这个强引用被回收时, 弱引用会被自动回收.


		ThreadLocal<M> tl = new ThreadLocal<>();
     	tl.set(new M());
        tl.remove();

在这里插入图片描述
ThreadLocal中的map中的键是当前这个对象 tl , key值弱引用指向ThreadLocal, 因为Thread往往是长期存在的, 如果key不是弱引用, 那么将一直不会被回收, 此时就造成了内存泄漏, 使用弱引用指向ThreadLocal, 当tl对象被回收时, 这个key就会自动消失.
尽管如此, 还是会有内存泄漏存在, ThreadLocal被回收, key值也变为null, 则导致整个Value再也无法被访问, 因此依然存在内存泄漏, 所以使用ThreadLocal, 对象不使用了, 务必remove掉
这也是ThreadLcao最需要注意的地方

WeakHashMap的作用

虚引用

在这里插入图片描述
虚引用被回收时, 这个虚引用会装到这个队列中, 当这个对象被干掉时, 就会往这个队列扔进一个值

import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.util.LinkedList;
import java.util.List;

public class test04 {
    private static final List<Object> LIST = new LinkedList<>();
    private static final ReferenceQueue<M> QUEUE = new  ReferenceQueue<>();

    public static void main(String[] args) {
        PhantomReference<M> phantomReference = new PhantomReference<>(new M(),QUEUE);
        new Thread(()->{
            while (true){
                LIST.add(new byte[1024*1024]);
                try {
                    Thread.sleep(1000);
                }catch (InterruptedException e){
                    e.printStackTrace();
                    Thread.currentThread().interrupt();
                }
                System.out.println(phantomReference.get());
            }
    }).start();

        new Thread(()->{
            while (true){
                Reference<? extends M> poll =QUEUE.poll();
                if(poll!=null){
                    System.out.println("虚引用对象被jvm回收了"+poll);
                }
            }
    }).start();
        try {
            Thread.sleep(500);
        }catch (InterruptedException e){
            e.printStackTrace();
        }

    }
}

虚引用是get到的值都是null

在这里插入图片描述
DirectByteBuffer直接内存, 是不被JVM直接管理的内存, 被操作系统管理. 当这个buffer为空, 那么没有办法回收, 就要用到虚引用, 当虚引用被回收时, 接到通知, 就到堆外内存去回收这个buffer.
Java堆外内存回收Unsafe类

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值