当new一个对象时,对象优先在新生代Eden区分配内存。如果Eden无法提供足够的内存空间,则JVM会发起一次Minor GC。
当new一个大对象(需要大量连续内存空间的java对象)时,对象直接在老年代分配。具体大对象的大小,可通过-XX:PretenureSizeThreshold参数来配置,大于此参数的对象直接进入老年代。
长期存活的对象将进入老年代。在新生代中有一个和对象年龄有关的计数器(AgeCounter),每当家对象经历一次Minor GC存活下来之后,此对象的AgeCounter就加1,当AgeCounter达到一定的值(用参数-XX:MaxTenuringThreshold表示)就会晋升到老年代。
对于对象年龄的判定,并不一定要达到阈值才能进入老年代,如果在Survivor区中年龄相同的所有对象大小总和大于Survivor空间的一半,大于或等于此年龄的对象可直接进入老年代。
每一次Minor GC之前,会进行担保条件检查,如下图所示:
Minor GC:发生在新生代的垃圾收集动作,非常频繁,速度极快。
Major GC:发生在老年代的垃圾收集动作,速度慢,比Minor GC慢10倍,每次Major GC至少会伴随一次Minor GC。
Full GC:发生在新生代和老年代的垃圾收集动作,速度慢,需要stop the world。
详细JVM的内容请查看https://docs.oracle.com/en/java/javase/12/vm/index.html。