G1 GC采用不同的方式分配内存,下面这些图片用来解释G1系统的原理
1、G1的堆结构
堆是一块内存区域分成许多固定大小的区域
区域的大小由JVM启动的时候决定的,一般在1-32M范围内,大约生成2000个左右。
2、G1堆的分配
事实上,这些区域在逻辑上被映射到三大区:Eden, Survivor, 和老年代
图片中的颜色表示了区域和它被赋予的角色,存活的对象被腾挪(复制或者拷贝),从一个区域到另一个区域。区域中的收集被设计成和应用程序并行的。
如图所示,区域可以被分配为Eden, Survivor, 和老年代区域,此外还有第四种,我们称之为Humongous区域。这些区域被设计为保存一个标准区域大于50%的对象。他们被存储为一块连续的区域。这种类型的区域必须是没有被使用的区域(译者注:翻译到这里,暂且不明白,接着往下读)
注:在写这篇文章的时候,对Humongous对象的收集还没得到优化,你应该避免创建这样打的对象。(译者注:更云里雾里了,这个Humongous是指一个区域的类型,还是一些对象的类型呢?)
3、G1中的年轻代
堆被分成接近2000块区域,最小1Mb,最大32Mb。蓝色区域存储老年代对象,绿色区域存储年轻代对象。
注:这些区域不需要像老的GC那样必须是连续的
4、G1中年轻代的收集
存活的对象被复制或者移动到一个或多个survivor区域,如果满足老化阈值,这些对象就会被晋升到老年代(译者注:老化、晋升的概念就是说,一个对象在经历n个周期的收集仍然存活,这个对象就是可能被程序长期持有不愿释放的对象,这个对象就算是老化了,晋升到老年代)
这个阶段会发生stop the world的暂停,Eden和survivor的大小需要计算,为了进入下一次的年轻代收集,一些信息的统计也同时进行,为了帮助这个计算。设定的目标暂停时间也会纳入考虑的因素。
这个方法让改变这些区域大小变的容易,根据需要增大或者减少。
5、年轻代GC之后
存活的对象已经被复制或者移动到survivor和老年代区域。
刚晋升的对象如深蓝色所表示,绿色的表示survivor区域
总结一下,关于年轻代的GC有如下几点:
- 一整块堆内存被分成多个小区域
- 年轻代是由一些列的不连续的区域组成的,这有助于随时改变它的大小
- 年轻代的垃圾收集,或者称年轻代GC,是stop-the-world的一个事件,所有的应用程序线程必须停止,等待这个操作完成。
- 年轻代的GC,又多个线程并行处理
- 存活的对象被复制或者移动到新的survivor区域或者老年代区域
除非注明,赵岩的博客文章均为原创,转载请以链接形式标明本文地址
本文地址:https://zhaoyanblog.com/archives/414.html