wky233 的个人博客

记录精彩的程序人生

Open Source, Open Mind,
Open Sight, Open Future!
  menu
40 文章
10233 浏览
1 当前访客
ღゝ◡╹)ノ❤️

JVM(二)垃圾回收方法

JVM 垃圾收集的区域是 Java 堆和方区,JVM 垃圾回收99%是对 Java 堆中的垃圾回收,只有 1%是对方法区进行垃圾回收。从上一篇的 Java 堆的介绍也说了,绝大部分的对象和数组分配在 Java 堆中,线程私有的区域不需要垃圾回收

判断对象是否存活

引用计数法

给对象添加一个引用计数器,每当有地方引用就加一,当引用实效时就减一,当技术器为零时就表明这个对象已经死了,引用计数法实现的方法简单,效率高,但是存在两个对象互相引用的问题。
image.png
就比如上图,当把栈里 Obj1-reference=null,Obj2-reference=null,那么下面的两个实例对象互相引用,此时引用次数都变为 1,但两个对象已经不能用了,应该标记对象已死然后回收掉,这就是引用计数法的弊端。

可达性分析法

这个是目前 JVM 判断对象是否存活的方法,通过一系列的“GC Roots”的对象作为起始点,从 GC Roots 开始向下搜索,搜索所走过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是不可用的。不可达对象。
在 Java 语言中,GC Roots 包括:
虚拟机栈中引用的对象。
方法区中类静态属性实体引用的对象。
方法区中常量引用的对象。
本地方法栈中 JNI 引用的对象。
image.png

四种垃圾回收算法

标记-清除法

顾名思义,先把需要回收的对象标记上,然后再统一把标记的对象清除掉,这样缺点就是,会造成大量的空间碎片,造成空间浪费。如果朝生息死的对象很多的话,标记和清除的效率也不高。

复制算法

开辟两个内存大小完全相等的空间,先把对象都分配到一个空间内,当空间用完时,就开始回收对象,将存活的对象复制到另一个空间,然后把用过的空间清空。
这样以来,不会产生空间碎片,清除的效率也高。缺点就是内存变为原来的一半了,如果长期存活的对象很多的话,复制效率并不高。

标记-整理法

就是标记-清除法的升级版,前面和标记-清除法过程一样,只不过在统一清除对象后,将存活的对象整理到空间的一端,提高空间利用率。正因为这点,它回收

分代收集算法

根据对象生命周期的长短,把 Java 堆分为新生代和老年代,对于一个项目来言,许多对象都是朝生息死的,就把新生得对象都放在新生代。当然也有长期存活的对象,比如连接池中的对象,Session 对象等,把长期存活的对象从新生代移动到老年代,老年代里存放的都是长期存活的对象,对于新生代采用复制算法,因为新生对象多但存活的对象少,清除效率很高, 对于老年代存活数量多,需要回收的对象少,则用标记-整理法,或者标记-清除法。


标题:JVM(二)垃圾回收方法
作者:wky181
地址:https://www.wkyhky.site/articles/2019/10/14/1571016544956.html