JVM 垃圾回收

垃圾回收算法

一、垃圾回收算法

标记清除
  • 标记GC Root不可达对象,然后清除。存在内存碎片问题
标记整理
  • 标记GC Root不可达对象,然后清除,将存活的对象移动到一端。避免了内存碎片的问题
复制算法
  • 将内存分为相同的两部分,每次使用一块内存,垃圾回收时将存活的移到到另外一块。存在问题就是浪费内存
分代回收算法
  • 分为新生代和老年代。新生代分为eden和两个survivor区,新生代采用复制算法,每次回收都有98%的对象死亡,将存活的对象存入一个survivor区,当下次回收时将eden区和survivor区存活的对象存入另一个survivor区。每次垃圾回收存活对象年龄加1,达到设置的阈值时,对象进入老年代存储。大对象直接进入老年代。老年代一般采用标记清除或者标记整理算法。

二、对象什么时候进入老年代

  • 大对象直接进入老年代:大对象一般是很长的字符串或者数组。虚拟机提供了一个参数,当对象大于这个参数则直接进入老年代。
  • 长期存活的对象进入老年代:每次Minor GC,存活对象的年纪就加1,当对象的年纪大于设定的阈值时,进入老年代。
  • 动态对象进入老年代:若个survivor区域中,相同年龄对象的总和大于survivor区域的一半,那么大于等于该年龄的对象进入老年代

三、空间分配担保

  • 在Minor GC之前,会判断老年代最大可用连续内存空间是否大于新生代对象,如果大于那么Minor GC是安全,否则看是否开启了空间担保,开启了则判断老年代最大可用连续内存空间是否大于历次晋升到老年代对象的平均大小,大于则进行一次Minor GC(存在风险,担保失败则还会进行Full GC),否则进行Full GC

四、安全点

  • JVM在进行GC时,会暂停所有线程,同时GC前后对象的引用关系不能发生变化。目前主流的虚拟机采用的准确式GC,就是通过OopMap数据结构记录,在JIT编辑的时候OopMap会在特定位置记录栈和寄存器的引用位置,GC的时候只要扫描OopMap就能知道哪些垃圾可以被回收。
  • OopMap特定的位置就是安全点,安全点不能太少,不然GC等待时间太长,也不能太多,不然过于频繁,影响性能,安全点一般选择调用方法,循环跳转,异常跳转等地方。
  • GC时一般分为抢断式和主动式暂停线程,抢断式时暂停所有线程,如果线程没有到达安全点,那么继续运行到安全点。主动式,GC时设置一个标志,线程到达标志位时轮询这个标识,如果标志为真,就挂起线程,标志的位置和安全点重合
  • GC时,有些线程无法主动挂起,如sleep,这个时候线程没有CUP资源。会设定一个安全区域,安全区域中对象的引用关系不会发生变化,当进入这个区域时会进行标记该线程进入安全区域,GC时就不需要管这些安全区域的线程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值