背景
Java 中的对象优先在 Eden 分配,当 Eden 区满时会触发 Minor GC。
Minor GC 的耗时
- 标记过程的耗时。
- 复制过程的耗时。
- 如果开启了 GC 日志,打印日志的耗时。
新生代对象晋升到老年代有多种情况
- 触发 Minor GC 时,Eden 区和一个 Survivor 区中存活的对象大于另一个 Survivor 区的大小,则通过分配担保机制进入老年代。
- 若对象太大, 新生代无法容纳这个对象,直接进入老年代。
- 长期存活的对象将进入老年代。对象的年龄达到 MaxTenuringThreshold 晋升到老年代。
- 动态对象年龄判定。如果在 Survivor 区中相同年龄的对象的所有大小之和超过 Survivor 空间的一半,此时说明已经容纳不下对象了,因为 Survivor 区真实可用的空间为 Survivor 区的一半,所以直接晋升老年代。
Survivor 的意义
Survivor 的存在意义是减少被送到老年代的对象,进而减少 Full GC 的发生。
Survivor 为什么要划分为两块
目的:
解决内存碎片的问题。
流程
JVM 把新生代中的 Survivor 区分为两块,一块用来放存活对象,另一块什么都不放。当新生代发生 Minor GC 时,把 Eden 区中存活的对象和一块用来放存活对象的 Survivor 区中的存活对象复制到另一块 Survivor 区中,并且清空 Eden 区和当前这块 Survivor 区。