JVM-GC是什么

1、分代收集算法

新生代:复制收集算法(年轻代特点是内存空间相对老年代较小,对象存活率低。

复制算法的效率只和当前存活对象大小有关,因而很适用于年轻代的回收。而复制算法的内存利用率不高的问题,可以通过虚拟机中的两个Survivor区设计得到缓解。

老年代:标记清除+标记整理算法(老年代的特点是内存空间较大,对象存活率高。

这种情况,存在大量存活率高的对象,复制算法明显变得不合适。一般是由标记清除或者是标记清除与标记整理的混合实现。

次数上频繁收集Young区

次数上较少收集Old区

基本不动元空间

2、GC四大算法

1)引用计数法

2)复制算法(Copying)

年轻代中使用的是Minor GC ,这种GC算法采用的是复制算法()

Minor GC 会把Eden中的所有活的对象都移到Survivor区域中,如果Survivor区中放不下,那么剩下的活的对象就被移到Old generation中,也即一旦收集后,Eden是就变成空的了。

当对象在Eden出生后,在经过一次MinorGC后,如果对象还存活,并且能够被另外一块Survivor区域所容纳,则使用复制算法将这些任然存活的对象复制到另外一块Survivor 区域中,然后清理所使用过的Eden以及Surivor区域,并且将这些对象的年龄设置为1,以后对象在Survivor区没熬过一次MinorGC,就将对象的年龄+1,当对象的年龄到达某个值时(默认是15岁,通过-XX:MaxTenuringThreshold来设定参数),这些对象就会成外老年代

HotSpot JVM把年轻代分为了三个部分:1个Eden区和2个Survivor区(分别叫from和to)。默认比例为8:1:1,一般情况下,新创建的对象都会被分配到Eden区(一些对象特殊处理),这些对象经过第一次Minor GC后,如果任务存活,将会被移动Survivor区。对象在Survivor区中每熬过一次MinorGC,年龄就会增加1岁,当它的年龄增加到一定程度是,就会被移动到老年代中,因为年轻代中的对象基本都是朝生夕死(90%以上),所以在年轻代的垃圾回收算法使用的是复制算法,复制算法的基本思想就是将内存分为两块,每次只用其中一块,当这一块内存用完,就将还活着的对象复制到另外一块上面,复制算法不会产生内存碎片

 

在GC开始的时候,对象只会存在于Eden区和名为from的Survivor区,Survivor区to是空的。紧接着进行GC,Eden区中所有存活的对象都会被复制到to,而在from区中,仍存活的对象会根据他们的年龄值来决定去向。年龄达到一定值(默认15)的对象会被移动到老年代中,没有达到阈值的对象会被复制到to区域。经过这次GC后,Eden区和from区已经被清空。这个时候,from和to会交换他们的角色,也就是新的to就是上次GC前的from,新的from就是上次GC前的to。不管怎样,都会保证名为to的Survivor区域是空的。Minor GC会一直重复这样的过程,直到to区被填满,to区被填满之后,会将所有对象移动到老年代中

因为Eden区对象一般存活率较低,一般的,使用两块10%的内存作为空闲和活动区间,而另外80%的内存,则是用来给新建对象分配内存的。一旦发生GC,将10%的from活动区间与另外80%中存活的Eden区对象转移到10%的to空闲区间,接下来,将之前90%的内存全部释放,以此类推。

缺点:

浪费了一半的内存

复制操作耗时(当对象存活率达到一定程度是) 

3)标记清除(Mark-Sweep)

老年代一般是由标记清除或者是标记清除与标记整理的混合实现

算法分发标记和清除两个阶段,先标记出要回收的对象,然后同意回收这些对象

 

用通俗的话解释一下标记清除算法,就是当程序运行期间,若可以使用的内存被耗尽的时候,GC 线程就会被触发并将程序暂停,随后将要回收的对象标记一遍,最终统一回收这些对象,完成标记清理工作接下来便让应用程序恢复运行。

总结就是:

1、标记和清除两个操作,有两次扫描,耗时严重,会产生内存碎片

2、触发这个算法会使得程序暂停,的操作完成以后才能让应用程序恢复运行

 

4)标记也压缩(Mark-Compact)

1、标记

原理与标记清除一样

2、压缩

再次扫描,并发一端滑动存活对象

 

 

 

总结:

没有内存碎片,可以利用bump  

需要移动对象的成本

(1)内存效率: 复制算法 > 标记清除算法 > 标记整理算法(此处的效率只是简单的对比时间复杂度,实际情况不一定如此)。
(2)内存整齐度: 复制算法 = 标记整理算法 > 标记清除算法。
(3)内存利用率: 标记整理算法 = 标记清除算法 > 复制算法。

年轻代: 

3、GC算法总体概述

JVM在进行GC时,并非每次都对上面三个内存区域一起回收的,大部分时候回收的都是指新生代。

因此GC按照回收的区域又分为了两种类型,一种是普通GC(minor GC),一种是全局GC(Major GC or Full GC)

普通GC:只针对新生代区域的GC,指发生在新生代的垃圾收集动作,因为大多数Java对象存活率都不高,所有MinorGC 非常频繁,一般回收速度也比较快

全局GC:指发生在老年代的垃圾收集动作,出现了Major GC,经常会伴随至少一次的Minor GC(但不是绝对)。Major GC 的速度一般要比Minor GC慢上10倍以上

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追逐路上的小人物

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值