技术理论-【JVM】-03-堆实现分代算法

分代算法

背景
JVM中堆是存放java对象的地方,也是内存管理的核心对象。
前面在垃圾收集器中已经介绍了GC会带来2个问题,“碎片问题”和“效率问题”,为了解决这两个问题,人们不断的再优化垃圾回收算法,已经介绍了常用的引用计数、标记清除、复制、标记整理。
现在让我们来研究JVM当前采用的最优算法 ,分代算法。

理论
首先引入了java对象年龄的概念,每次GC操作作为一年,存活下来的对象年龄都+1;
然后对不同年龄段的对象进行分区管理,分为新生代老年代两个区,新生代又分为两部分Eden区和Survival区,Survival区又分为From区和To区;
最后针对新生代和老年代采用不同的垃圾回收策略。

在这里插入图片描述

为什么要引入对象年龄和分代概念呢?

因为大部分java对象都是“朝生夕死”,频繁的创建和回收,根据“28定律”可以得出只有20%的对象是需要长期存活的。为了提升GC效率,没必要对整个堆进行频繁的垃圾回收。

所以先将堆分成两大部分,根据对象年龄来决定对象保存的区域,对象成年标准就是分代的标准,比如设定为16岁,大于16岁进入老年代。

分代算法的具体操作流程

  1. 新生代中创建Eden区(伊甸园),所有对象从这里出生;
  2. 每次GC后,Eden区和From区中幸存的对象将进入To区,保证Eden和From每次都清空,不存在碎片问题;
  3. 每次GC后,To区中的幸存的对象如果成年了将进入老年代;
  4. To区中的幸存的对象如果未成年,这样造成To区产生碎片,为了解决这个问题,GC后都将From和To的标识互换,这样下次GC时,又可以重复步骤2;

在这里插入图片描述

垃圾收集器分类

结合垃圾回收算法和堆的分代模型,可以得到新生代和老年代对应的垃圾收集器。

新生代:

  1. 串行收集器Serial、ParNew、
  2. 并发收集器Parallel
  3. 理想收集器G1

老年代:

  1. 并发收集器CMS
  2. 串行收集器ParNew Old、
  3. 并发收集器Parallel Old
  4. 理想收集器G1

在这里插入图片描述

垃圾收集触发时机

在这里插入图片描述

从对象在堆的分代区流动的过程,可以清晰的看出对象都是从Eden创建的,当对象创建时内存不够了,肯定就会触发垃圾回收。

既然堆已经分代,新生代和老年代的GC触发频率肯定是不一样的,又可以将GC分类为Minar GC(新生代)、Major GC(老年代)、Full GC(新生代+老年代+持久带+其他)。根据对象区域流动过程,那个区域满了,就会触发对应区域的GC。

创建对象失败,首先触发Minar GC,如果不能解决问题,再触发 Major GC,如果还是不行就要触发Full GC。

除了创建对象失败之外,系统还会定时自动进行Minar GC,还可以手动 触发System.gc()。

总结触发GC时机

  1. 创建对象失败;
  2. 手动触发;

持久带

由于JAVA8之后将方法区直接改成了本地内存机制,彻底解决方法区溢出问题,就不再需要考虑持久带的内存管理问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值