java的reference类型简介

java reference 类型简介

在日常的java开发中,我们很多时候都是通过以下方式创建对象和引用

Person person = new Person()

这里创建的就是一个强引用,那么有人就会说了,难道还有其他类型的引用,答案是肯定的,在java中包含四种类型的引用

一、强引用

如上所叙述,这种直接创建引用的都属于强引用,生命周期,引用与对象的指向关系没有去掉之前,对象在gc阶段不能被回收

二、弱引用

相对与强引用来说,弱引用在gc阶段,引用所指向的对象将被强制的回收

弱引用的创建方式

public static void main(String[] args) {

    WeakReference<Integer> weakRef = new WeakReference(128);
    System.out.println("GC前:"+weakRef.get());
    System.gc();
    System.out.println("GC后:"+weakRef.get());
}

上述代码的运行结果:

GC前:128
GC后:null

由此我们可以看到,执行了System.gc操作,弱引用的对象已经被回收了,注意:这里之所以用128,因为对于整数来说,-128~127的值使用的是缓存里的值,不会被回收

三、软引用

软引用只会在内存不足的情况下才会进行回收,如果内存充足,则不回收

用例如下:

public static void main(String[] args) {
    //定义一个软引用列表
    List<SoftReference<Integer>> softList = new ArrayList<>();

    for(int i=0;i<5000;i++){
        softList.add(new SoftReference<Integer>(new Integer(i)));
    }
    //存活的引用数
    int activeRefNum = 0;
    for(SoftReference softRef:softList){
        if(softRef.get()!=null){
            activeRefNum++;
        }
    }

    System.out.println("当前存活的引用数:"+activeRefNum);

    List list = new ArrayList();
    for(int i=0;i<10000;i++){
        list.add(i);
    }

    activeRefNum = 0;
    for(SoftReference softRef:softList){
        if(softRef.get()!=null){
            activeRefNum++;
        }
    }

    System.out.println("当前存活的引用数:"+activeRefNum);
}

当内存充足的情况下执行结果如下

GC前存活的软引用数:5000
GC后存活的软引用数:5000

当设置jvm 运行参数为 -Xms1m -Xmx1m ,执行结果如下:

GC前存活的软引用数:5000
GC后存活的软引用数:0

四、虚引用

虚引用,一种较为特殊的引用,该引用不能拿来存值,当你创建了虚引用以后,你不能通过get方法来获取值,相当于没有引用,这个引用主要可以拿来作为监控使用,因为当垃圾回收器确定回收对象的时候,会把引用放入到ReferenceQueue中,可以通过poll queue获取当前要被回收的引用对象

jvm参数:-Xms5m -Xmx5m

public static void main(String[] args) {
    final ReferenceQueue queue = new ReferenceQueue();

    PhantomReference<Integer> phantomRef = new PhantomReference<>(128,queue);

    //start一个线程进行监控
    new Thread(new Runnable() {
        @Override
        public void run() {
            while(true) {
                Reference ref = queue.poll();
                if(ref!=null){
                    System.out.println("--- 虚引用对象被jvm回收了 ----");
                    System.exit(1);
                }
            }
        }
    }).start();

    //初始化一个list,不停的添加数据,出发jvm gc
    List list = new ArrayList();
    new Thread(new Runnable() {
        @Override
        public void run() {
            while (true) {
                list.add(new byte[1024 * 50]);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("phantomRef的referent:"+phantomRef.get());
            }
        }
    }).start();
}

执行结果如下:

phantomRef的referent:null
phantomRef的referent:null
phantomRef的referent:null
--- 虚引用对象被jvm回收了 ----

转载于:https://my.oschina.net/u/946498/blog/2963053

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值