JVM分代算法

      目前JVM虚拟机中基本都使用分带收集算法,根据对象存活周期不同,分为三个年代:年青代、老年代、持久代。这是因为不同对象存活时间不一致,有些可能只使用一次,使用后就需要回收,而有些对象却会伴随整个程序的生命周期。分代有利于堆不同生命周期的对象进行管理,减少GC次数,提高运行效率。

1、年青代

      年青代包含一个eden区,两个survivor区,默认比例为8:1:1。

         

      新创建的对象基本都会存放在EDEN区(大对象直接放在老年代),而这部分对象大部分都会“朝生暮死”,使用后被快速回收。常规一次回收可回收70%-95%的空间,效率非常高。

       年青代采用复制算法进行回收,假如当前正在使用的是eden及survivor1区,大部分新生对象都会放在eden区(大对象会直接放在老年代),当eden区内存满了以后,会将存活对象保存到survivor2区,eden进行Minor GC。survivor1区的存活对象根据年龄(默认是15,每经历一轮GC,年龄加1)决定去向,年龄达到阀值,复制到老年代,若年龄未到,复制到survivor2区,survivor1区清空。如果survivor2区内存不足以存放所有的存活对象,则需要以来老年代的担保机制将部分对象复制到老年代。

2、老年代

      新生代与老年代默认比例为1:2,老年代用来存放存活时间较长,但还是会死的对象信息(如缓存对象、单例对象等)。老年代对象来源有一下几个方向:

          ①大部分来自于年青代,对象在年青代存活时间过阀值,就会被复制到老年代。

          ②年青代中部分对象虽然为过阀值,但是因为survivor区已满,由担保机制复制到老年代。

          ③部分大对象直接在老年代创建,不经历年青代,如长字符串、长数组等需要大量连续空间的对象。

      老年代一版采用标记-整理算法或标记-清除算法,如果采用年青代的复制算法,效率较低。老年代对象存活时间较久,回收频率较低。

3、持久代

      保存在方法区,保存类的信息(构造器),常量,静态变量等,一般不进行垃圾回收,但是不是不会进行垃圾回收,这点需要注意。

4、分析比较

      ①年青代及老年代保存在堆中,堆=年青代+老年代,比例为1:2。

      ②持久代在方法区。

猜你喜欢

转载自blog.csdn.net/u011861874/article/details/81480473