Administrator
Administrator
Published on 2025-01-13 / 0 Visits
0
0

2024.12.20

空间分配担保机制

在每一次执行 Young GC 之前,虚拟机会检查老年代的最大可用的连续空间是否大于新生代的所有对象的总空间。

如果大于,那么说明本次 Young GC 是安全的。

如果小于,那么虚拟机会查看 HandlePromotionFailure(JDK 7 已移除)参数设置的值判断是否允许担保失败。如果值为true,那么会继续检查老年代最大可用连续空间是否大于历次晋升老年代的对象的平均大小(一共有多少对象在内存回收后存活下来是不可预知的,因此只好取之前每次垃圾回收后晋升到老年代的对象大小的平均值作为参考)。如果大于,则尝试进行一次 Young GC ,但这次 Young GC 依然是有风险的;如果小于,或者 HandlePromotionFailure的值为 false,则会直接触发一次 Full GC。

JDK 7 之后不再支持HandlePromotionFailure参数,直接检查老年代最大可用连续空间是否大于历次晋升到老年代的对象的平均大小。

担保的结果可能成功,也可能失败。所以,在 Young GC 的复制阶段执行之后,会发生以下三种情况:

  • 剩余的存活对象大小,小于 Survivor 区,那就直接进入 Survivor 区。

  • 剩余的存活对象大小,大于 Survivor 区,小于老年代可用内存,那就直接去老年代。

  • 剩余的存活对象大小,大于 Survivor 区,且大于老年代,触发 Full GC。

JIT

JVM 中内置了解释器(interpreter),在运行时对字节码进行解释翻译成机器码,然后再执行。

解释器的执行方式是一边翻译,一遍执行,因此执行效率很低。为了解决低效问题,HotSpot 引入了 JIT 技术(Just-In-Time)。

有了 JIT 技术之后,JVM 还是通过解释器进行解释执行。但是,当 JVM 发现某个方法或代码块运行时执行的特别频繁的时候,就会认为这是“热点代码”(Hot Spot Code)。然后 JIT 会把部分“热点代码”翻译成本地机器相关的机器码,并进行优化,然后再把翻译后的机器码缓存起来,以备下次使用。


Comment