Java虚拟机(JVM)-- GC四大算法之复制算法

Posted Z && Y

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java虚拟机(JVM)-- GC四大算法之复制算法相关的知识,希望对你有一定的参考价值。

1. 复制算法


新生区中使用的是Minor GC,采用的就是复制算法(Copying)

什么是复制算法?

  • Minor GC 会把Eden中的所有活的对象都移到Survivor区域中,如果Survivor区中放不下,那么剩下的活的对象就被移动到老年代中,也就是说,一旦收集后,Eden就是变成空的了
  • 当对象在Eden(包括一个Survivor区域,这里假设是From区域)出生后,在经过一次Minor GC后,如果对象还存活,并且能够被另外一块Survivor区域所容纳 (上面已经假设为from区域,这里应为to区域,即to区域有足够的内存空间来存储Eden 和 From 区域中存活的对象),则使用复制算法将这些仍然还活着的对象复制到另外一块Survivor区域(即 to 区域)中,然后清理所使用过的Eden 以及Survivor区域(即form区域),并且将这些对象的年龄设置为1,以后对象在Survivor区,每熬过一次Minor GC,就将这个对象的年龄 + 1,当这个对象的年龄达到某一个值的时候(默认是6,最大值是15,通过-XX:MaxTenuringThreshold 设定参数)这些对象就会进入老年代。

原理解释:

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

  • 在GC开始的时候,对象只会在Eden区和名为 “From” 的Survivor区,Survivor区“TO” 是空的,紧接着进行GC,Eden区中所有存活的对象都会被复制到 “To” , 而在 “From” 区中,仍存活的对象会更具他们的年龄值来决定去向。年龄达到一定值 的对象会被移动到老年代中,没有达到阈值的对象会被复制到 “To区域”,经过这次GC后,Eden区和From区已经被清空,这个时候, “From” 和 “To” 会交换他们的角色,也就是新的 “To“ 就是GC前的”From“ , 新的 ”From“ 就是上次GC前的 ”To“。不管怎样,都会保证名为To 的Survicor区域是空的。 Minor GC会一直重复这样的过程。直到 To 区 被填满 , ”To “ 区被填满之后,会将所有的对象移动到老年代中。
  • 因为Eden区对象一般存活率较低,一般的,使用两块10%的内存作为空闲和活动区域,而另外80%的内存,则是用来给新建对象分配内存的。一旦发生GC,将10%的from活动区间与另外80%中存活的Eden对象转移到10%的to空闲区域,接下来,将之前的90%的内存,全部释放,以此类推;

好处:没有内存碎片,坏处:浪费内存空间

劣势:

1、他浪费了一半的内存,这太要命了(to永远是空的)
2、如果对象的存活率很高,我们可以极端一点,假设是100%存活,那么我们需要将所有对象都复制一遍,并将所有引用地址重置一遍。复制这一工作所花费的时间,在对象存活率达到一定程度时,将会变的不可忽视,所以从以上描述不难看出。复制算法要想使用,最起码对象的存活率要非常低才行,而且最重要的是,我们必须要克服50%的内存浪费。



以上是关于Java虚拟机(JVM)-- GC四大算法之复制算法的主要内容,如果未能解决你的问题,请参考以下文章

JVM 虚拟机笔记

JVM虚拟机垃圾回收(GC)算法及优缺点

Java 虚拟机原理垃圾回收算法 ( 设置 JVM 命令参数输出 GC 日志 | GC 日志输出示例 | GC 日志分析 )

gc算法与内存分析(jvm)

JVM之GC算法的实现(垃圾回收器)

JVM系列第14讲:JVM参数之GC日志配置