java的四种引用

强软弱虚

普通的引用就是强引用——Object o=new Object,只要还有变量指向该对象,gc就一定不会回收。注:垃圾回收的优先级很低,system.gc()不一定能立刻触发垃圾回收

示例

public static void main(String[] args) {
    Person person = new Person();
    System.out.println(person);
    person=null;
    System.gc();
    for(int i=0;i<10;i++){
        System.out.println("阻塞垃圾回收");
    }
}
输出结果
Person{name='null'}
阻塞垃圾回收
阻塞垃圾回收
阻塞垃圾回收
阻塞垃圾回收
阻塞垃圾回收
阻塞垃圾回收
阻塞垃圾回收
阻塞垃圾回收
阻塞垃圾回收
阻塞垃圾回收
调用垃圾回收器

软引用的使用方式——SoftRefernce
软引用所指向的对象reference ,只有堆内存不够时,gc才会回收reference。主要用于缓存

使用方法

public class TestCitation {
    public static void main(String[] args) {
        TestCitation testCitation = new TestCitation();
        testCitation.softCitation();
    }

    /**
     * 强引用
     */
    public void strongCitation(){
        //强引用
        Person person = new Person();
        System.out.println(person);
        person=null;
        System.gc();
        for(int i=0;i<10;i++){
            System.out.println("阻塞垃圾回收");
        }
    }

    /**
     * 软引用
     */
    public void softCitation(){
        SoftReference<byte[]> reference = new SoftReference<>(new byte[1024*1024*10]);
        System.out.println(reference.get());
        System.gc();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(reference.get());
        byte[] bytes = new byte[1024 * 1024 * 15];
        System.out.println(reference.get());
    }
}
输出结果
[B@4554617c
[B@4554617c
null

gc干活就会被回收。
只要强引用被回收,弱引用所对应的引用也会被回收,不需要做额外处理。一般用于容器中。ThreadLocal是用ThreadLocalMap实现,ThreadLocalMap存储的key-value的key值是ThreadLocal,ThreadLocalMap用的就是弱引用
ThreadLocalMap实现

static class Entry extends WeakReference<ThreadLocal<?>> {
    /** The value associated with this ThreadLocal. */
    Object value;

    Entry(ThreadLocal<?> k, Object v) {
        super(k);
        value = v;
    }
}

使用方式

WeakReference<Person> weakReference = new WeakReference<>(new Person());
System.out.println(weakReference.get());
System.gc();
try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    e.printStackTrace();
}
System.out.println(weakReference.get());
输出结果
Person{name='null'}
null

WeakHashMap

public void weakHashMapCitation(){
    WeakHashMap<Person, String> weakHashMap = new WeakHashMap<>();
    Person person = new Person();
    person.setName("123");
    weakHashMap.put(person,"xdfsdf");
    System.out.println(weakHashMap);
    person=null;
    System.gc();
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println(weakHashMap);
}
输出结果
{Person{name='123'}=xdfsdf}
{}

管理堆外内存,写jvm用,写程序不需要。一旦虚引用指向的person被回收,则把该对象放在queue队列中。只要gc工作,就一定会回收虚引用对象。虚引用无法获取里面的值,主要是为了通知。堆外内存无法由jvm回收
使用场景
管理堆外内存——DirectByteBuffer

大概写法

PhantomReference<Person> reference = new PhantomReference<Person>(new Person(), queue);

使用方式

定义虚内存并把内存塞满

PhantomReference<Person> reference = new PhantomReference<Person>(new Person(), queue);
LinkedList<Object> objectList = new LinkedList<>();
new Thread(()->{
    while (true){
        objectList.add(new byte[1024*1024*5]);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(reference.get());
    }
}).start();
再开多个线程检测队列是否为空
new Thread(()->{
    while (true){
        Reference<? extends Person> poll = queue.poll();
        if(poll!=null){
            System.out.println("触发垃圾回收——————————"+poll);
        }
    }
}).start();

运行结果

null
null
触发垃圾回收——————————java.lang.ref.PhantomReference@2d46c162
null
Exception in thread "Thread-0" java.lang.OutOfMemoryError: Java heap space
	at com.me.thread.TestCitation.lambda$phantomCitation$0(TestCitation.java:88)
	at com.me.thread.TestCitation$$Lambda$1/821270929.run(Unknown Source)
	at java.lang.Thread.run(Thread.java:745)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值