JVM内存结构以及GC各种回收算法

1.jvm内存结构大致可以分为6个区域,参考下图:

2.GC相关算法介绍

  2.1 标记-清除算法

  标记清除算法简单快速,但是缺点是会产生很多的内存碎片。开辟内存空间需要的是连续的内存空间,比如需要开辟一个比较大的内存区域,且内存区域足够,但是是由很多内存碎片组成的,这就会导致一个问题的出现,有足够的内存空间,但是却无法使用。

  

  2.2 复制算法

  复制算法采取的是将内存对半分的策略。即总是保留一块空着的区域,将存活的对象复制到另外一半未使用的区域,然后清空原来使用的区域,虽然避免了内存碎片问题,但是导致内存的浪费。相当于每次都只能使用50%的内存。

  

  2.3 标记-整理算法

  标记-整理算法避免了标记-清除算法的内存碎片问题以及标记复制算法的内存浪费问题,但是整理过程会降低GC的效率。

  

  2.4 分代算法

  考虑到上述三种算法的优缺点,在JVM中,综合使用。研究发现,内存中的对象,大致可以分为两类,一类是生命周期很短的,比如局部变量,另一类是生命周期比较长的,比如通信连接中的connection对象。分代算法将内存区域划分为三大块,年轻代(Young Generation)、老年代(old Generation)、永久代(permanent Generation)。

  

  流程:

  1.刚开始时,对象分配在Eden区域,from、to 为空。

  2.随着应用的运行,越来越多的对象呗分配到Eden区域,当Eden区域没有足够的内存空间时,就会发生minor GC(Young GC),这里会标记出可回收对象,然后将存活对象移动到from区,接着可回收对象被清理掉,Eden区域成空区域。

  3.过了一段时间,Eden区域内存空间又满了,将会再次触发minor GC,同样还是先做标记,这时候Eden区和from区都有可能有可以回收的对象,但这时候to区是空的,Eden区和from区存活的对象直接复制到to区域,然后将Eden区和from区的可回收对象清理掉,经过这一轮的minor GC后,Eden 区和 from区变成了空的。

  4.又过了一段时间,Eden区可能又没有内存空间 ,会再一次触发minorGC,由于to 区域之前有对象,这一轮GC的时候,会有可被回收的对象,这时候Eden区和to区存活的对象将会被复制到from区域,接着Eden区和from区的回收对象将被清除掉,这一轮GC后,to区域又变成了空区域。

      对于那些在from区和to区来回移动的对象,会降低GC的效率,于是就有了年龄的概念。对象在年轻代三块区域(Eden、from、to)每从一个区域移动到另外一个区域,这个对象的年龄将会加1,当这个对象的年龄在年轻代中达到一定的年龄后,这个对象将晋升成老年代。如果老年代也存满了,将会发生major GC(也称为Full GC)。老年代采用的是标记-整理算法,这种算法效率低下,耗时长,故应该尽减少major GC。

猜你喜欢

转载自www.cnblogs.com/chaiming520/p/11765796.html