jvm之GC垃圾回收算法整理

jvm垃圾回收机制

一般来说jvm对于初中级程序员来说很少用的到,但是现在jvm基本上是所有大厂必问的知识点了,想进大厂拿高工资这是必须掌握的了,接下来我会从几个方面讲解,希望会对大家有所帮助。

一、jvm垃圾定位算法
首先我们要明白什么是可回收垃圾对象,那就是看这个堆里面的对象有没有被栈中的引用指向它,
有的话就不是垃圾对象,反之如果没有被指向就是垃圾对象,用代码举个简单例子

public class HelloWord {


    public static void main(String[] args) {
        HelloWord hw=new HelloWord();
    }
}

hw是存放在栈中的引用,指向堆中的Helloword对象,这会HelloWord是不属于垃圾对象的。接下来我们在这里面加一行代码

public class HelloWord {


    public static void main(String[] args) {
        HelloWord hw=new HelloWord();
        hw=null;
    }
}

当我们把这个引用置为null的时候这个对象就没有引用指向它了,这会就是垃圾回收对象了。

在java中是有两种算法来判断这个对象是否是可回收对象
1、引用计数法
简单来说就是给这个对象加一个引用计数器,每当这个对象被引用的时候,这个计数器就加1,当引用失效的时候这个计数器就减1,我们只需要判断这个引用计数器就可以,任何引用计数器为0的对象都是垃圾可回收对象。
方法比较简单,效率也比较高效,但是很遗憾在主流的jvm中并没有用这种算法来判断,因为它没有办法解决对象间互相引用的问题,这里我用一段代码解释下循环引用

public class HelloWord {

//定义一个成员变量
Object instance=null;

   public static void main(String[] args) {
       HelloWord hw1=new HelloWord();
       HelloWord hw2=new HelloWord();
       //内部引用指向
       hw1.instance=hw2;
       hw2.instance=hw1;
    
      hw1=null;
      hw2=null;
   
   }
}

这个时候这两个对象已经是垃圾可回收对象了,因为没有栈中的引用指向它,但是由于对象内部还存在引用,因此这会计数器的值并不是0,所以就会判断失败了。
2,可达性分析算法

核心思想为 通过一系列称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索走过的路径称为“引用链”,
当一个对象到 GC Roots 没有任何的引用链相连时(从 GC Roots 到这个对象不可达)时,证明此对象不可用。
在Java语言中,可作为GC Roots的对象包含以下4种:

虚拟机栈(栈帧中的本地变量表)中引用的对象。(可以理解为:引用栈帧中的本地变量表的所有对象)
方法区中静态属性引用的对象(可以理解为:引用方法区该静态属性的所有对象)
方法区中常量引用的对象(可以理解为:引用方法区中常量的所有对象)
本地方法栈中(Native方法)引用的对象(可以理解为:引用Native方法的所有对象)

二、jvm回收算法
1、标记清除法
标记清楚法从名称来看,可以拆分两个阶段:标记(mark)和清除(sweep)。
(1)标记阶段
在此阶段垃圾回收器会从应用程序根对象开始遍历,每一个可从跟对象访问到的对象都会添加一个标识。
(2)清除阶段
在此阶段中,垃圾回收器,会对堆内存从头到尾进行线性遍历,如果发现有对象没有被标识为可到达对象,

那么就将此对象占用的内存回收,并且将原来标记为可到达对象的标识清除,以便进行下一次垃圾回收操作。
缺点:标记和清除两个过程的效率都不高,并且会产生大量的内存碎片,这样程序后如果在运行中需要用到比较大的内存的时候,就不得不触发另一次的垃圾回收动作
2、复制算法
简单说就是将内存分成两个大小一样的空间,每次使用只用其中的一个,当内存用完了的时候就把活着的存活对象复制到另一个上,这样就是每次都是对整个半区进行回收,当然不会有空间碎片的问题,只是这种做法会牺牲一半的内存空间,代价有点高了。
缺点:牺牲内存空间
优点:效率高
3、标记整理法
标记的过程和标记清除算法一样,只是后续的步骤会有所差别,不是直接回收,而是让可存活的对象向一段进行移动,然后清理掉边界以外的内存,这样就不会空间碎片的问题了
缺点:效率低
优点:不会有空间碎片
总结:复制算法和标记整理都是在标记清楚之上改进的算法,真正实际运用的时候,是多个算法综合运用的,新生代中每次回收垃圾都会有大批量的对象死亡,那就采用复制算法,只需要付出少量的复制成本就可以完成垃圾回收,而老年代中因为存活率较高,所以我们使用标记清楚或者标记整理算法来回收。
本文是自己在工作中和学习中的一些总结,欢迎大家一起交流

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值