JVM针对年轻代和老年代的GC算法有什么区别
JVM针对年轻代和老年代的GC算法有以下区别:年轻代采取的是复制算法,老年代采用的是标记-清除算法或标记–整理算法。年轻代也被称为“新生代”,主要用来存放新生的对象,采用复制算法只需付出少量对象的复制成本即可完成垃圾收集。
1.JVM中GC算法概述
GC(垃圾回收)是由JVM(Java 虚拟机)垃圾回收器提供的一种对内存回收的一种机制,它一般会在内存空闲或者内存占用过高的时候对那些没有任何引用的对象不定时地进行回收。GC常用的回收算法一般有:标记-清除算法、标记-整理算法、复制算法。
- 标记-清除算法是最基础的收集算法,该算法的优点是当存活对象比较多的时候,性能比较高,因为该算法只需要处理待回收的对象,而不需要处理存活的对象。
- 标记-整理算法,最大的优势便是使得内存上面不会再有碎片问题,并且新对象的分配只需要通过简单的指针碰撞便可完成。
- 复制算法的优势是:①不会产生内存碎片;②标记和复制可以同时进行;③复制时也只需要移动栈顶指针即可,按顺序分配内存,简单高效;④每次只需要回收一块内存区域即可,而不用回收整块内存区域,所以性能会相对高效一点。
2.年轻代和老年代的GC算法区别
JVM将Java堆内存划分为了两个区域:年轻代和老年代,其中年轻代也被称为“新生代”,新生代中每次使用的空间不超过90%,主要用来存放新生的对象;而老年代里面存放都是生命周期长的对象,对于一些较大的对象(即需要分配一块较大的连续内存空间),是直接存入老年代的,还有很多从新生代的Survivor区域中熬过来的对象。
在年轻代中,每次收集都会有大量对象死去(只有少量存活),因此对象的存活时间都比较短,所以可以选择复制算法,只需要付出少量对象的复制成本就可以完成每次垃圾收集。
而老年代中,存在大量存活时间长的对象,采用复制算法的时候会要求复制的对象较多,效率也就急剧下降;而且由于对象存活几率是比较高,也没有额外的空间对它进行分配担保,所以必须选择“标记-清除”或“标记-整理”算法进行垃圾收集。
延伸阅读
JVM中的永久代是什么
JVM中的堆一般分为三大部分,即新生代、老年代、永久代。其中,永久代指的是永久保存区域,用于存放JDK自身所携带的Class,Interface的元数据,也就是说它存储的是运行环境必须的类信息,被装载进此区域的数据是不会被垃圾回收器回收掉的,关闭JVM才会释放此区域所占用的内存。
Classic在被加载的时候被放入永久区域,它和存放的实例的区域不同,在Java8中,词锋代已经被移除,取而代之的是一个称之为“元数据区”(元空间)的区域。元空间和永久代类似,都是对JVM中规范中方法的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存的限制。类的元数据放入native memory,字符串池和类的静态变量放入java堆中。这样可以加载多少类的元数据就不再由MaxPermSize控制,而由系统的实际可用空间来控制。
采用元空间而不用永久代的原因:
- 为了解决永久代的OOM问题,元数据和class对象存放在永久代中,容易出现性能问题和内存溢出。
- 类及方法的信息等比较难确定其大小,因此对于永久代大小指定比较困难,大小容易出现永久代溢出,太大容易导致老年代溢出(堆内存不变,此消彼长)。
- 永久代会为GC带来不必要的复杂度,并且回收效率偏低。

