java的四种引用方式

import com.zb.gc.Test2;

import java.lang.ref.*;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

public class Reference1 {

    public static void main(String[] args) {
        title("强引用");
        strangeReferenceTest();

        title("软引用");
        softReferenceTest();

        title("弱引用");
        weakReferenceTest();

        title("虚引用");
        phantomReferenceTest();

        title("虚引用2");
        phantomReferenceTest2();
    }

    private static void title(String title) {
        System.out.println();
        System.out.println();
        System.out.println(title);
    }

    private static void printMemory(String message, Reference<byte[]> sr) {
        System.out.println(message + ", 结果:sc=" + sr.get());
    }

    private static void printMemory(String message, Object obj) {
        System.out.println(message + ", 结果:sc=" + obj);
    }

    /**
     * ==========================================================
     * ==========强引用、软引用、弱引用、虚引用
     * ==========================================================
     */
    //强引用
    private static void strangeReferenceTest() {
        //1.设定堆空间大小:VM.options='-Xmx20m'

        //2.开辟内存空间10MB(软引用)
        byte[] oldMemory = new byte[1024 * 1024 * 10];
        printMemory("一阶段:开辟10MB", oldMemory);//查看内存地址

        //3.gc主动回收
        System.gc();
        printMemory("二阶段:GC回收", oldMemory);//查看内存地址

        //4.开辟新内存空间10MB(强引用)
        byte[] newMemory = new byte[1024 * 1024 * 10];
        printMemory("三阶段:再开辟10MB", oldMemory);//查看内存地址
    }

    //软引用:当[gc_full]时释放
    private static void softReferenceTest() {
        //1.设定堆空间大小:VM.options='-Xmx20m'

        //2.开辟内存空间10MB(软引用)
        SoftReference<byte[]> sr = new SoftReference<>(new byte[1024 * 1024 * 10]);
        printMemory("一阶段:开辟10MB", sr);//查看内存地址

        //3.gc主动回收
        System.gc();
        printMemory("二阶段:GC回收", sr);//查看内存地址
        
        //4.开辟新内存空间10MB(强引用)
        byte[] newMemory = new byte[1024 * 1024 * 10];
        printMemory("三阶段:再开辟10MB", sr);//查看内存地址
    }

    //弱引用:当[手动gc]时释放
    private static void weakReferenceTest() {
        //1.设定堆空间大小:VM.options='-Xmx20m'

        //2.开辟内存空间10MB(弱引用)
        WeakReference<byte[]> wr = new WeakReference<>(new byte[1024 * 1024 * 10]);
        printMemory("一阶段 开辟10MB", wr);//查看内存地址

        //3.gc主动回收
        System.gc();
        printMemory("二阶段 GC回收", wr);//查看内存地址

        //4.开辟新内存空间10MB(强引用)
        byte[] newMemory = new byte[1024 * 1024 * 10];
        printMemory("三阶段 再开辟10MB", wr);//查看内存地址
    }

    private static final ReferenceQueue<byte[]> QUEUE = new ReferenceQueue<>();

    //虚引用:开辟在主内存而不是jvm内存,跟gc无关
    private static void phantomReferenceTest() {
        //1.设定堆空间大小:VM.options='-Xmx20m'

        //2.开辟内存空间10MB(虚引用)
        PhantomReference<byte[]> pr = new PhantomReference<>(new byte[1024 * 1024 * 10], QUEUE);
        printMemory("一阶段 开辟10MB", pr);//查看内存地址

        //3.gc主动回收
        System.gc();
        printMemory("二阶段 GC回收", pr);//查看内存地址

        //4.开辟新内存空间10MB(强引用)
        byte[] newMemory = new byte[1024 * 1024 * 10];
        printMemory("三阶段 再开辟10MB", pr);//查看内存地址
    }

    private static final List<byte[]> LIST1 = new LinkedList<>();
    private static final ReferenceQueue<Reference1> QUEUE1 = new ReferenceQueue<>();

    private static void phantomReferenceTest2(){
        //开辟内存空间10MB
        PhantomReference<Reference1> pr = new PhantomReference<>(new Reference1(), QUEUE1);

        printMemory("一阶段 开辟10MB", pr);

        //循环在LIST1中开辟内存空间10MB
        new Thread(()->{
            while(true){
                LIST1.add(new byte[1024 * 1024]);
                printMemory("二阶段 循环开辟10MB", pr);
            }
            //内存不足之后,M对象会被回收,会放入到QUEUE中
        }).start();

        //
        new Thread(()->{
            while(true){
                Reference<? extends Reference1> poll = QUEUE1.poll();
                if(poll != null) {
                    System.out.println("三阶段 虚引用对象被JVM回收" + poll);
                }
            }
        }).start();
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值