用实际代码展示SoftReference的应用

Full GC后,如果JVM内存依然不足,就会回收只有软引用的对象。

JVM发生 OutOfMemoryError 时,也会回收只有软引用的对象。

这段代码,程序会不断抛出OOM异常,抛出异常后年轻代和年老代都会被干净。

package test;

import org.junit.Test;

import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * @author: zyp
 * @since: 2021/12/14 下午6:48
 */
public class TestSoftReference {
    /**
     * 用SoftReference持有一个链表, 一直往链表里面放东西
     * 发生OOM时, SoftReference持有的链表就会被回收
     * 这时候换一个SoftReference继续放东西
     * 整个过程对SoftReference的引用都是强引用
     *
     * @param
     * @return void
     * @author zhengyongpan
     * @since 2021/12/14 下午7:04
     */
    @Test
    public void test() {
//        保存软引用
        List<SoftReference<List>> refs = new ArrayList<>();
//        当前使用的软引用
        SoftReference<List> ref = new SoftReference<>(new LinkedList());
        while (true) {
            try {
                List list = ref.get();
                if (list != null) {
                    list.add(new byte[10240]);
                } else {
//                    被回收掉了, 换一个SoftReference
                    System.err.println("被回收掉了");
                    ref = new SoftReference<>(new LinkedList());
                    refs.add(ref);
                }
            } catch (OutOfMemoryError x) {
                x.printStackTrace();
//                OOM了, 换一个SoftReference
                ref = new SoftReference<>(new LinkedList());
                refs.add(ref);
            }
        }
    }

}

这段代码,JVM内存不足时,会进行FullGC,将SoftReference持有的byte[]对象进行回收

package test;

import org.junit.Test;

import java.lang.ref.SoftReference;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * @author: zyp
 * @since: 2021/12/14 下午6:48
 */
public class TestSoftReference {

    @Test
    public void test() throws InterruptedException {
        List<SoftReference<byte[]>> list = new LinkedList<>();
        int addCount = 0;
        int gcCount = 0;
        while (true) {
            try {
                list.add(new SoftReference<>(new byte[1024 * 1024 * 100]));
                addCount++;
                Iterator<SoftReference<byte[]>> iterator = list.iterator();
                int aliveCount = 0;
                while (iterator.hasNext()) {
                    SoftReference<byte[]> next = iterator.next();
                    if (next.get() != null) {
                        aliveCount++;
                    } else {
//                        内存不足,被回收掉了
                        gcCount++;
                        iterator.remove();
                    }
                }
                System.out.println(String.format("生成对象 %s, 回收对象 %s, 存活对象 %s", addCount, gcCount, aliveCount));
            } catch (OutOfMemoryError x) {
                x.printStackTrace();
            }
            Thread.sleep(100);
        }
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值