强弱软虚引用 weakHashMap

强引用

这是最常见的引用关系,变量o对 new object()这个对象(下称对象xx)的进行引用,o持有对象的强引用,宁愿内存溢出也不清除强引用的内存

Object obj = new Object();//o 持有这个新new出来对象xx的强引用
//不需要之后 将obj置为null,这样对象xx就没有引用了,变为不可达,会在下次gc的时候回收掉
obj = null;//help GC

obj置为null的情况下,如果想继续对对象xx进行引用处理,只能再次new一个出来,在这种场景下,jdk1.2后出了一个java.lang.ref包,加强了对对象的生命周期的控制,同时也可以作为java的内置缓存,使得在引用不可达的情况下 仍可以被使用

引用类图

软引用SoftReference

丢到SoftReference中就是软引用,内存快溢出了就把软引用的干掉

    @Test
    public void test1() throws Exception {
        //软引用
        Object obj = new Object();
        ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
        SoftReference<Object> softReference = new SoftReference<Object>(obj,queue);
        System.out.println("原始obj:" + obj);//java.lang.Object@32a1bec0
        obj = null;//删除强引用
        System.gc();//手动gc
        Thread.currentThread().sleep(1000);//确保gc执行
        System.out.println("null obj:" + obj);
//        queue.poll();//软弱虚引用gc后对象就会放入queue  而poll操作则是拿出队列的头对象 即取得并删除
        System.out.println("软引用 get :" + softReference.get());//内存足够 不会gc  java.lang.Object@32a1bec0

        //弱引用
        Object obj2 = new Object();
        WeakReference<Object> weakReference = new WeakReference<Object>(obj2,queue);
        obj2 = null;
        System.gc();
        Thread.currentThread().sleep(1000);
        System.out.println("弱引用 get :" + weakReference.get());//内存足够 也会被gc null 对象放入queue    }

弱引用WeakReference

一旦执行GC就会清除

虚引用

使用很少

当多种引用关系并存的时候以那个为准呢?
强引用>软引用>弱引用>虚引用 当然是以强的为主
比如前面代码的若是obj不置为null,那即便obj有软/弱引用,那对象也是强引用

GC交互原理

个人推测,gc底层算法中会对各种不同引用采用不对的算法,对不同GCroot采用策略对待
对于gc与queue的交互,即便看了Reference/ReferenceQueue的源码,也还是不明白GC时为何就会将数据丢入queue中,Reference中的守护线程只是改变状态而已也是GC底层算法

WeakHashMap

看名字就知道和弱引用有很大关系,发现很多框架使用这个map
其内部的Entry维护了一个

/**
     * The entries in this hash table extend WeakReference, using its main ref
     * field as the key.
     */
    private static class Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V> {
        V value;
        final int hash;
        Entry<K,V> next;

        /**
         * Creates new entry.
         */
        Entry(Object key, V value,
              ReferenceQueue<Object> queue,
              int hash, Entry<K,V> next) {
            super(key, queue);
//创建了弱引用 以key的弱引用 即key变为null时 会被回收掉 和value无关
            this.value = value;
            this.hash  = hash;
           xt  = next;
        }}
     * 
     /**
     * Expunges stale entries from the table.get/size等使用map时就会调用这个方法
     */
    private void expungeStaleEntries() {
        for (Object x; (x = queue.poll()) != null; ) {
            synchronized (queue) {
    //queue.poll()从queue取出并删除x,然后对比map中key 并从map中删除这个entry 即自动回收
    }

参考https://blog.csdn.net/coolwxb/article/details/7939246

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值