垃圾回收器和垃圾回收算法

举报
上善若水. 发表于 2022/11/30 12:12:56 2022/11/30
【摘要】 垃圾回收器、垃圾回收算法垃圾回收器有多个,先说新生代的三个垃圾回收器,serial,parnew,parallel scavenge,然后再说老年代的serial old,parallel old,cms,最后在说一下新生代和老年代都使用的垃圾回收器G1吧。SerialSerial是新生代下使用复制算法,单线程运行的垃圾回收器,简单高效,没有线程交互开销,专注于GC,这个垃圾回收器工作的时候...

垃圾回收器、垃圾回收算法
垃圾回收器有多个,先说新生代的三个垃圾回收器,serial,parnew,parallel scavenge,然后再说老年代的serial old,parallel old,cms,最后在说一下新生代和老年代都使用的垃圾回收器G1吧。

Serial
Serial是新生代下使用复制算法,单线程运行的垃圾回收器,简单高效,没有线程交互开销,专注于GC,这个垃圾回收器工作的时候会将所有应用线程全部冻结,而且是单核cpu,所以基本不会考虑使用它。

ParNew
ParNew是新生代下使用复制算法,多线程运行的垃圾回收器,可以并行并发GC,和serial对比,除了多核cpu并行gc其他基本相同。

Parallel scavenge
Parallel scavenge也是新生代下使用复制算法,可以进行吞吐量控制的多线程回收器,主要关注吞吐量,通过吞吐量的设置控制停顿时间,适应不同的场景。可以发现新生代的垃圾回收器都使用,复制算法进行gc。

复制算法
新生代中每次垃圾回收都要回收大部分对象,所以为了避免内存碎片化的缺陷,这个算法按内存容量将内存划分为大小相等的两块,每次只使用其中一块,当这一块存活区内存满后将gc之后还存活的对象复制到另一块存活区上去,把已使用的内存清掉。

分代收集算法
按照分代收集算法的思想,把应用程序可用的堆空间分为年轻代,老年代,永久代,然后年轻代有被分为Eden区和二个Survivor存活区,这个比例又可以分为8比1比1。当第一次eden区发生minor gc,会把存活的对象复制到其中的一个Survivor区,然后eden区继续放对象,直到触发gc,会把eden区和之前存放对象的Survivor区一起gc,二个区存活下来的对象,复制到另一个空的Survivor里面,这二个区就清空,然后将二个存活区角色互换。

进入老年代的几种情况
当对象在Survivor区躲过一次GC 后,年龄就会+1,存活的对象在二个Survivor区不停的移动,默认情况下年龄到达15的对象会被移到老生代中,这是对象进入到老年代的第一种情况。

这里就会有个问题,JVM分代年龄为什么是15次?
一个对象的GC年龄,是存储在对象头里面的,一个Java对象在JVM内存中的布局由三个部分组成,分别是对象头、实例数据、对齐填充。而对象头里面有4个bit位来存储GC年龄。

4个bit位能够存储的最大数值是15,所以从这个角度来说,JVM分代年龄之所以设置成15次是因为它最大能够存储的数值就是15。虽然JVM提供了参数来设置分代年龄的大小,但是这个大小不能超过15。从设计角度来看,当一个对象触发了最大值15次gc,还没有办法被回收,就只能移动到old generation了。另外,设计者还引入了动态对象年龄判断的方式来决定把对象转移到old generation,也就是说不管这个对象的gc年龄是否达到了15次,只要满足动态年龄判断的依据,也同样会转移到old generation。

第二种情况就是,创建了一个很大的对象,这个对象的大小超过了jvm里面的一个参数max tenuring thread hold值,这个时候不会创建在eden区,新对象直接进入老年代。

第三种情况,如果在Survivor区里面,同一年龄的所有对象大小的总和大于Survivor区大小的一半,年龄大于等于这个年龄对象的,就可以直接进入老年代,举个例子,存活区只能容纳5个对象,有五个对象,1岁,2岁,2岁,2岁,3岁,3个2岁的对象占了存活区空间的5分之三,大于这个空间的一半了,这个时候大于等于2岁的对象,需要移动到老年代里面,也就是3个2岁的,一个3岁的对象移动到老年代里面。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。