3年前 (2022-02-07)  Java系列 |   抢沙发  997 
文章评分 1 次,平均分 5.0

在本文中,我们将了解JVM的Code Cache 代码缓存。

什么是Code Cache?

简而言之,JVM Code Cache (代码缓存)是JVM存储编译成本机代码的字节码的区域。我们将可执行本机代码的每个块称为nmethodnmethod可能是一个完整的或内联的Java方法。

即时(JIT)编译器是代码缓存区的最大消费者。这就是为什么一些开发人员将此内存称为JIT代码缓存。

Code Cache优化

代码缓存的大小是固定的。一旦它满了,JVM就不会编译任何额外的代码,因为JIT编译器现在处于关闭状态。此外,我们将收到“CodeCache is full… The compiler has been disabled”警告消息。因此,我们的应用程序的性能最终会下降。为了避免这种情况,我们可以使用以下大小选项调整代码缓存:

  • InitialCodeCacheSize–初始代码缓存大小,默认为160K
  • ReservedCodeCacheSize–默认最大大小为48MB
  • CodeCacheExpansionSize–代码缓存的扩展大小,32KB或64KB

增加ReservedCodeCacheSize可能是一个解决方案,但这通常只是一个临时解决办法。

幸运的是,JVM提供了一个UseCodeCache刷新选项来控制代码缓存区域的刷新。其默认值为false。当我们启用它时,它会在满足以下条件时释放占用的区域:

  • 代码缓存已满;如果该区域的大小超过某个阈值,则会刷新该区域
  • 自上次清理以来已过了特定的时间间隔
  • 预编译代码不够热。对于每个编译的方法,JVM都会跟踪一个特殊的热度计数器。如果此计数器的值小于计算的阈值,JVM将释放这段预编译代码

Code Cache使用

为了监控Code Cache(代码缓存)的使用情况,我们需要跟踪当前正在使用的内存的大小。

要获取有关代码缓存使用情况的信息,我们可以指定–XX:+PrintCodeCache JVM选项。运行应用程序后,我们将看到类似的输出:

CodeCache: size=32768Kb used=542Kb max_used=542Kb free=32226Kb

让我们看看这些值的含义:

  • 输出中的大小显示内存的最大大小,与ReservedCodeCacheSize相同
  • used是当前正在使用的内存的实际大小
  • max_used是已使用的最大尺寸
  • free是尚未占用的剩余内存

PrintCodeCache选项非常有用,因为我们可以:

  • 看看什么时候会flushing
  • 确定我们是否达到了关键内存使用点

分段代码缓存

从Java9开始,JVM将代码缓存分为三个不同的段,每个段都包含特定类型的编译代码。更具体地说,有三个部分:

  • 非方法段包含JVM内部相关代码,例如字节码解释器。默认情况下,该段约为5MB。此外,还可以通过-XX:nonNMethoddeHeapSize调整标志配置段大小
  • 分析的代码段包含经过轻微优化的代码,其生命周期可能很短。即使默认情况下段大小约为122 MB,我们也可以通过-XX:ProfiledCodeHeapSize调整标志来更改它
  • 未分析的代码段包含完全优化的代码,其生命周期可能很长。类似地,默认情况下大约为122MB。当然,这个值可以通过-XX:nonprofiedCodeHeapSize调整标志进行配置

这种新结构以不同的方式处理各种类型的编译代码,从而提高了整体性能。

例如,将短命编译代码与长寿命代码分离可以提高方法清理器的性能——主要是因为它需要扫描更小的内存区域。

小结

本文简要介绍了JVM Code Cache (代码缓存)。

此外,我们还提供了一些使用和调整选项来监视和诊断该内存区域。

 

除特别注明外,本站所有文章均为老K的Java博客原创,转载请注明出处来自https://javakk.com/2571.html

关于

发表评论

表情 格式

暂无评论

登录

忘记密码 ?

切换登录

注册