强软弱虚四种引用

java中四种引用,强软弱虚

  • 强引用:

只要有引用指向某个对象,这个对象就不会被回收=====这个就是最普通的new Object()

  • 软引用:

这个可以用在缓存中,数据都放在里面,允许内存不够的情况下把这个数据释放掉

    @Test
    public void tet1() throws InterruptedException {
        SoftReference<byte[]> sr = new SoftReference<>(ByteBuffer.allocate(1024 * 1024 *10).array());
        System.out.println(sr.get());
//        System.gc();
        TimeUnit.SECONDS.sleep(1);
        System.out.println(sr.get());
        ByteBuffer.allocate(1024 * 1024 * 15);
        System.out.println(sr.get());
    }

结果:

[B@6b57696f
[B@6b57696f
null

  • 弱引用:

只要遇到了gc,就直接回收

作用在于:只要有一个强引用指向了这个对象,那么托管就交给了那个强引用。只要强引用“不关心”这个对象了,那么弱引用也就可以直接被回收掉

####一般用在容器里面

ThreadLocal

threadlocal存储本次线程变量,独享资源。

set(object)的时候,以这个threadlocal作为key,将这个key和value放入到map中

其中map中的key使用的是弱引用。在这个情况下,只要是强引用消失了,map中的key也消失掉了。

坑:虽然key弱引用消失了,但是value是强引用,只有在线程销毁的时候才会消失,所以如果不停的往threadlocalmap里面放值,那么value的强引用就一直在,可能造成oom

所以,使用完必须使用remove方法,防止内存泄露

WeakHashMap

首先看一下它创建entry的代码

从这里我们可以看到其内部的Entry继承了WeakReference,也就是弱引用,所以就具有了弱引用的特点。不过还要注意一点,那就是ReferenceQueue,他的作用是GC会清理掉对象之后,引用对象会被放到ReferenceQueue中。

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) {
        // key是弱引用,但是value不是
        // 同时传入了一个referenceQueue队列,被垃圾回收掉的Entry会放入到这个引用队列里面
        super(key, queue);
        this.value = value;
        this.hash  = hash;
        this.next  = next;
    }
}

当gc发生,强引用失效的部分,会被放入队列。然后不管是请求put(),get(),还是size()等等方法,都会调用到到expungeStaleEntries()方法,这个方法会将entry的value=null,方便gc回收

/**
 * Expunges stale entries from the table.
 */
private void expungeStaleEntries() {
    for (Object x; (x = queue.poll()) != null; ) {
        synchronized (queue) {
            @SuppressWarnings("unchecked")
                Entry<K,V> e = (Entry<K,V>) x;
            int i = indexFor(e.hash, table.length);
            Entry<K,V> prev = table[i];
            Entry<K,V> p = prev;
            while (p != null) {
                Entry<K,V> next = p.next;
                if (p == e) {
                    if (prev == e)
                        table[i] = next;
                    else
                        prev.next = next;
                    // Must not null out e.next;
                    // stale entries may be in use by a HashIterator
                    e.value = null; // Help GC
                    size--;
                    break;
                }
                prev = p;
                p = next;
            }
        }
    }
}

 

  • 虚引用

基本上用不到。虚引用 使用的是堆外内存,不会被jvm所管理,用来管理堆外内存使用的。

弱引用使用get()方法还是可以拿到对应的值的,但是到虚引用的时候get()什么都拿不到。

netty会使用堆外内存,所以可能会用到

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值