【java】垃圾回收机制

判断是否是垃圾

在这里插入图片描述

橙色的三个区域的回收机制是确定的,只有绿色区域的回收是动态的,因此垃圾回收只考虑绿色区域。

引用计数法

给每个对象添加一个引用计数器,每当有一个地方引用它,计数器就+1,当引用失效,计数器就-1,计数器为0的对象就可以被当作垃圾收集了。

缺点:无法检测出循环引用的情况

public class ReferenceCounterProblem {
    public static void main(String[] args) {
        MyObject object1 = new MyObject();
        MyObject object2 = new MyObject();
        object1.childNode = object2;
        object2.childNode = object1;
    }
}

可达性分析算法

把所有引用的对象想象成一棵树,从树的根节点(GC Boots)出发,遍历找到所有树枝对象,这些称为“可达”对象,不能到达的则为可回收对象。

在这里插入图片描述

以下对象可以作为GC Boots:

  • 虚拟机栈(帧栈中的本地变量表)中引用的对象
  • 方法区中静态属性引用的对象
  • 方法区中常量引用的对象
  • 本地方法栈中 JNI 引用的对象

垃圾回收算法

标记-清理

利用可达性遍历内存,将“存活”对象和“垃圾”对象进行标记,然后再遍历一遍,把所有垃圾对象所占的空间清除即可。

  • 简单方便
  • 容易产生内存碎片

标记-整理

利用可达性遍历内存,将“存活”对象和“垃圾”对象进行标记,再把所有存活对象堆到同一个地方。

  • 适合存活对象多、垃圾少的情况
  • 需要整理过程

复制

将内存按容量划分成大小相等的两块,每次只用其中一块,当一块用完后,将还活着的对象复制一份到另一块上,再将当前块一次性清理掉。

  • 简单
  • 不会产生碎片
  • 空间利用率低,只用到了一半

堆和方法区的垃圾回收

方法区又叫做永久代。永久代的垃圾回收主要有两部分:废弃常量和无用的类。

废弃常量垃圾回收

  • 判定一个常量是否是废弃常量:没有任何一个地方对这个常量进行引用就表示是废弃常量。

  • 垃圾回收

无用的类垃圾回收

第一步:判定一个类是否是“无用的类”:需要满足下面三个条件

  • Java堆中不存在该类的任何实例,也就是该类的所有实例都被回收
  • 加载该类的ClassLoader已经被回收
  • 该类对应的Class对象在任何地方没有引用了,也不能通过反射访问该类的方法。

第二步:满足上面三个条件就可以回收了,但不是强制的。

注意:《java虚拟机规范》里面曾经说到过,不要求虚拟机对方法区进行垃圾回收。而且方法区进行垃圾回收性价比比较低。

堆的垃圾回收

在这里插入图片描述

  • 新生代:刚刚创建的对象,存活对象少,垃圾多
  • 老年代:存活了一段时间的对象,存活对象多,垃圾少
新生代:复制-回收机制

对于新生代区域,由于每次 GC 都会有大量新对象死去,只有少量存活。因此采用 复制-回收算法,GC 时把少量的存活对象复制过去即可。但是从上面我们可以看到,新生代也划分了三个部分比例:Eden:S1:S2=8:1:1。

其中 Eden 意为伊甸园,形容有很多新生对象在里面创建;S1和S2中的S表示Survivor,为幸存者,即经历 GC 后仍然存活下来的对象。

工作原理如下:

首先,Eden对外提供堆内存。当 Eden区快要满了,触发垃圾回收机制,把存活对象放入 Survivor A 区,清空 Eden 区;Eden区被清空后,继续对外提供堆内存;当 Eden 区再次被填满,对 Eden区和 Survivor A 区同时进行垃圾回收,把存活对象放入 Survivor B区,同时清空 Eden 区和Survivor A 区;当某个 Survivor区被填满,把多余对象放到Old 区;当 Old 区也被填满时,进行 下一阶段的垃圾回收。

老年代:标记整理-回收机制

老年代的特点是:存活对象多、垃圾少。因此,根据老年代的特点,这里仅仅通过少量地移动对象就能清理垃圾,而且不存在内存碎片化。也就是标记整理的回收机制。

垃圾回收相关函数

finalize()

finalize()是Object类中的方法,在垃圾回收器准备

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值