JVM-04.垃圾回收机制

思维导图:点击查看思维导图.

1. 判断一个对象可以被回收

1.1.引用计数法

一个对象如果没有任何与之关联的引用,即他们的引用计数都不为 0,则说明对象不太可能再被用到,那么这个对象就是可回收对象。如果被引用则引用计数+1。可能产生循环引用问题。

1.2.可达性分析

通过一系列的“GC roots”对象作为起点搜索。如果在“GC roots”和一个对象之间没有可达路径,则称该对象是不可达的。不可达对象不一定是可回收对象。不可达对象变为可回收对象至少要经过两次标记。两次标记后仍然是可回收对象,则将面临回收。
打印垃圾回收详细参数

-XX:+PrintGCDetail -verbose:gc

2.四种引用

2.1. 强引用

在 Java 中最常见的就是强引用,把一个对象赋给一个引用变量,这个引用变量就是一个强引用。只有所有GC Roots对象都不通过[强引用]该对象,该对象才会被垃圾回收。因此强引用是造成 Java 内存泄漏的主要原因之一。

2.2. 软引用

软引用需要用 SoftReference 类来实现,当系统内存足够时它就不会被回收,当系统内存空间不足时它会被回收。可以配合引用队列来释放软引用自身。软引用通常用在对内存敏感的程序中(内存不够,不重要的资源使用软引用)。
list对SoftReference强引用,byte[]对list弱引用
打印结果:
前4个对象为null已被回收!!!配合软引用队列后为软引用队列自身也将被回收,打印一个有值的对象地址!!

public static final int int_4MB = 4 * 1024 * 1024;
// -Xms15m -Xmx15m -Xmn10m
public static void main(String[] args) {
   
    List<SoftReference<byte[]>> list = new ArrayList<>();
    // 引用队列
    ReferenceQueue<byte[]> queue = new ReferenceQueue();
    for (int i = 0; i < 5; i++) {
   
        // 关联引用队列,当软引用所关联的byte[]被回收时,软引用会自己加到queue引用队列中
        SoftReference<byte[]> softReference = new SoftReference<>(new byte[int_4MB],queue);
        System.out.println(softReference.get()); // 打印了5个 [B@1540e19d ......
        list.add(softReference);
    }
    // 打印五个,前四个为null
    System.out.println("----------------------");
    for (SoftReference<byte[]> reference : list) {
   
        System.out.println(reference.get());  // 打印4个null,一个[B@6d6f6e28
    }
    // 将为null的移除
    // remove() 和 poll()都是用来从队列头部删除一个元素
    // queue为空时remove抛异常,poll返回null
    Reference<? extends byte[]> poll = queue.poll();
    while (poll != null) {
   
        list.remove(poll);
        poll = queue.poll();
    }
    // 添加了五个,发现只剩下一个了
    System.out.println("----------------------");
    for (SoftReference<byte[
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值