强弱软虚引用 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 queue = new ReferenceQueue();
        SoftReference softReference = new SoftReference(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 weakReference = new WeakReference(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 next;

        /**
         * Creates new entry.
         */
        Entry(Object key, V value,
              ReferenceQueue queue,
              int hash, Entry 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

你可能感兴趣的:(java学习笔记,JVM)