Java Oracle JVM 8:启用Codecache刷新时,刷新多少?

Java Oracle JVM 8:启用Codecache刷新时,刷新多少?,java,jvm,Java,Jvm,我正在运行一个Oracle Java 8 JVM(服务器,而不是客户端或嵌入式),ReservedCodeCacheSize=128M并启用UseCodeCache刷新。几天后,Codecache从93%的满度快速下降到80%。我假设我目睹了Codecache刷新,但令人惊讶的是,刷新后的大小接近100%满,而不是50%满 JVM如何决定要刷新多少Codecache 描述该选项,但不量化刷新的Codecache: 启用在关闭编译器之前刷新代码缓存。默认情况下,此选项处于启用状态。要在关闭编译器之

我正在运行一个Oracle Java 8 JVM(服务器,而不是客户端或嵌入式),ReservedCodeCacheSize=128M并启用UseCodeCache刷新。几天后,Codecache从93%的满度快速下降到80%。我假设我目睹了Codecache刷新,但令人惊讶的是,刷新后的大小接近100%满,而不是50%满

JVM如何决定要刷新多少Codecache

描述该选项,但不量化刷新的Codecache:

启用在关闭编译器之前刷新代码缓存。默认情况下,此选项处于启用状态。要在关闭编译器之前禁用代码缓存刷新,请指定-XX:-UseCodeCacheFlushing

说,

有一个JVM选项UseCodeCacheFlushing,可用于控制Codecache的刷新。启用此选项后,JVM调用一个紧急刷新,丢弃较旧的一半编译代码(nmethods),以在CodeCache中腾出可用空间

可以想象,较旧的一半编译代码只占整个Codecache的20%,但另一个可能的解释是,上面的博文不准确

“老一半”并不是所有nmethods的50%。用于扫描编译代码的热点逻辑有点复杂;最好的解释是它,但我将在下面给出一个简短的总结

如果至少满足以下条件之一,则调用清扫器:

  • 代码缓存已满
  • 自上次扫描以来,状态发生了足够多的更改(JDK 8测量的“足够”超过了ReservedCodeCacheSize的1%)
  • 自上次扫描以来,特定间隔已过去。代码缓存中的可用空间越多,调用清理程序的频率就越低。确切的公式是
  • 当清理程序运行时,它总是释放所有僵尸N方法,即未激活的已卸载、未优化或重新编译的方法

    此外,如果启用了
    UseCodeCacheFlushing
    ,则会释放足够冷的活动N方法。冷态方法的确定如下:

    • 在每个安全点,具有活动堆栈帧的N方法的热度计数器将重置为默认值。默认热度值为
      2*(ReservedDecacheSize/1MB)
    • 每次清扫器运行时,它将活动方法的热度计数器降低1
    • 如果热度计数器小于计算的阈值,则释放nmethod。阈值取决于代码缓存可用比率和-XX:NmethodSweepActivity选项(默认为10)。is
      NmethodSweepActivity
      越大,代码缓存空闲率越小,编译后的方法被扫描的越严重。这是公式
    因此,没有确切的数字显示有多少已编译的方法被清除。这是在运行时计算的,具体取决于保留的代码缓存大小、可用空间量、僵尸方法数量、冷方法数量和JIT人体工程学选项,如NmethodSweepActivity

    “上半部分”实际上并不意味着所有nMethod的50%。用于扫描编译代码的热点逻辑有点复杂;最好的解释是它,但我将在下面给出一个简短的总结

    如果至少满足以下条件之一,则调用清扫器:

  • 代码缓存已满
  • 自上次扫描以来,状态发生了足够多的更改(JDK 8测量的“足够”超过了ReservedCodeCacheSize的1%)
  • 自上次扫描以来,特定间隔已过去。代码缓存中的可用空间越多,调用清理程序的频率就越低。确切的公式是
  • 当清理程序运行时,它总是释放所有僵尸N方法,即未激活的已卸载、未优化或重新编译的方法

    此外,如果启用了
    UseCodeCacheFlushing
    ,则会释放足够冷的活动N方法。冷态方法的确定如下:

    • 在每个安全点,具有活动堆栈帧的N方法的热度计数器将重置为默认值。默认热度值为
      2*(ReservedDecacheSize/1MB)
    • 每次清扫器运行时,它将活动方法的热度计数器降低1
    • 如果热度计数器小于计算的阈值,则释放nmethod。阈值取决于代码缓存可用比率和-XX:NmethodSweepActivity选项(默认为10)。is
      NmethodSweepActivity
      越大,代码缓存空闲率越小,编译后的方法被扫描的越严重。这是公式

    因此,没有确切的数字显示有多少已编译的方法被清除。这是在运行时计算的,具体取决于保留的代码缓存大小、可用空间量、僵尸方法的数量、冷方法的数量以及JIT人体工程学选项,如您提到的OpenJDK源代码中的NmethodSweepActivity

    。你相信Oracle JVM使用相同的算法吗?@user100464是的,OpenJDK和Oracle JDK都运行相同的热点JVM,只是OpenJDK版本的JVM缺少某些商业功能。你提到了OpenJDK源代码。你相信Oracle JVM使用相同的算法吗?@user100464是的,OpenJDK和Oracle JDK都运行相同的热点JVM,只是OpenJDK版本的JVM缺少某些商业特性。