JVM区域总体分两类,heap区和非heap区。 heap区又分为:
- Eden Space(伊甸园)、
- Survivor Space(幸存者区)、
- Old Gen(老年代)。
1个Eden区和2个Survivor区(分别叫from和to)。默认比例为8:1,
非heap区又分:
- Code Cache(代码缓存区);
- Perm Gen(永久代);
- Jvm Stack(java虚拟机栈);
- Local Method Statck(本地方法栈);
在GC开始的时候,对象只会存在于Eden区和名为“From”的Survivor区,Survivor区“To”是空的。紧接着进行GC,Eden区中所有存活的对象都会被复制到“To”,而在“From”区中,仍存活的对象会根据他们的年龄值来决定去向。年龄达到一定值(年龄阈值,可以通过-XX:MaxTenuringThreshold来设置)的对象会被移动到年老代中,没有达到阈值的对象会被复制到“To”区域。经过这次GC后,Eden区和From区已经被清空。这个时候,“From”和“To”会交换他们的角色,也就是新的“To”就是上次GC前的“From”,新的“From”就是上次GC前的“To”。不管怎样,都会保证名为To的Survivor区域是空的。Minor GC会一直重复这样的过程,直到“To”区被填满,“To”区被填满之后,会将所有对象移动到年老代中。
动态对象年龄判定。
虚拟机并不总是要求对象的年龄必须达到MaxTenuringThreshold才能晋升到老年代,如果在Survivor区中相同年龄(设年龄为age)的对象的所有大小之和超过Survivor空间的一半,年龄大于或等于该年龄(age)的对象就可以直接进入老年代,无需等到MaxTenuringThreshold中要求的年龄。
图示: