Java堆中的新生代和老年代以及相应的垃圾收集算法

  • 新生代

主要是用来存放新生的对象,会频繁创建对象,所有垃圾收集会频繁进行回收。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。

复制算法将内存分为三个区:一块较大的Eden空间和两块较小的Survivor空间,每次使用Eden和其中一块Survivor。当回收时,将Eden和Survivor中还存活的对象一次性地复制到另外一快Servivor空间上,再清理掉Eden和刚才用过的Survivor空间。

  • 老年代

老年代的对象存活率高,故垃圾收集不会频繁执行。因为老年代中对象存活率高、也没有额外空间对他进行分配担保,就必须使用“标记—清理”或者“标记—整理”算法进行回收。使用复制算法则需要进行较多的复制操作,效率会变低。

永久代:

指内存的永久保存区域,主要存放Class和Meta(元数据)的信息。

Class在被加载的时候被放入永久区域。它和和存放实例的区域不同,GC不会在主程序运行期对永久区域进行清理。所以这也导致了永久代的区域会随着加载的Class的增多而胀满,最终抛出OOM异常。

在Java8中,永久代已经被移除,被一个称为“元数据区”(元空间)的区域所取代。

元空间的本质和永久代类似,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制。类的元数据放入 native memory, 字符串池和类的静态变量放入java堆中. 这样可以加载多少类的元数据就不再由MaxPermSize控制, 而由系统的实际可用空间来控制。

猜你喜欢

转载自blog.csdn.net/gary0917/article/details/83629597