首页 > 系统相关 >[转帖]深入JVM - Code Cache内存池

[转帖]深入JVM - Code Cache内存池

时间:2024-05-05 09:05:45浏览次数:25  
标签:Code 代码 Cache 转帖 编译 XX JVM

https://juejin.cn/post/6985913007142354958

 

1. 本文内容

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

2. Code Cache 简要介绍

简单来说,JVM会将字节码编译为本地机器码,并使用 Code Cache 来保存。 每一个可执行的本地代码块,称为一个 nmethod。 nmethod 可能对应一个完整的Java方法,或者是内联后的方法。

即时编译器(just-in-time,JIT)是代码缓存区的最大消费者,所以此区域又被开发者称为 JIT code cache。

3. 对 Code Cache 进行调优

code cache 区域的大小是固定的。

如果Code Cache区域用满了,就会停止JIT编译, 也就是说JVM不再编译任何代码。 我们还会收到 "CodeCache is full… The compiler has been disabled" 之类的告警消息。 JIT编译器关闭的结果,就是系统性能急剧下降。 为了避免这种情况,我们需要对Code Cache进行调优,例如使用以下参数:

  • InitialCodeCacheSize - 初始大小, 默认值为 160KB
  • ReservedCodeCacheSize - 保留给Code Cache的空间, 也就是最大空间, 默认值: 48MB
  • CodeCacheExpansionSize - 每次扩充的大小, 一般为 32KB 或者 64KB

合理地增加 ReservedCodeCacheSize 是一种解决办法, 毕竟现在很多应用加上依赖库的代码量一点都不少。 但我们也不能无限制地增大这个区域的大小。

幸运的是,JVM提供了一个启动参数 UseCodeCacheFlushing, 用来控制Code Cache的刷新。 这个参数的默认值为 false。 如果将其开启(-XX:+UseCodeCacheFlushing),则会在满足以下条件时释放占用的区域:

  • code cache用满; 如果该区域的大小超过某个阈值,则会刷新。
  • 自上次清理后经过了一定的时间间隔。
  • 预编译的代码不够热。 对于每个JIT编译的方法,JVM都会有一个热度跟踪计数器。 如果计数器的值小于动态阈值,则JVM会释放这段预编译的代码。

提示: 除非Code Cache不够用了,否则不要乱开;

4. 查看Code Cache的使用情况

想要监控代码缓存的使用情况,我们可以跟踪当前使用的内存大小。

指定JVM启动参数: -XX:+PrintCodeCache, 会打印Code Cache区的使用情况。 程序执行过程中, 我们可以看到类似下面的输出:

  shell 复制代码
$ java -XX:+PrintCodeCache -XX:+UseCodeCacheFlushing -version

CodeCache: size=245760Kb used=1060Kb max_used=1071Kb free=244699Kb

一起来分析下各个部分数值的含义:

  • size 表示此内存区域的最大值,与 ReservedCodeCacheSize 相等。
  • used 是此区域当前实际使用的内存大小。
  • max_used 是程序启动以来的历史最大使用量
  • free 是此区域尚未使用的空闲空间

PrintCodeCache 选项非常有用,可以帮助我们:

  • 查看何时进行了刷新(flushing)
  • 确定内存使用量是否达到关键点位

5. Code Cache分段

从Java 9开始,JVM将 Code Cache 细分为三个不同的段,每个段包含一种类型的编译代码。 具体是:

  • 非方法段(non-method segment), 保存相关的JVM内部代码,例如字节码解释器。 默认情况下,此段约为 5 MB。 可通过 -XX:NonNMethodCodeHeapSize 参数进行调整。
  • 待分析代码段(profiled-code segment), 包含经过简单优化的代码,使用寿命很短。 此段的大小默认为 122 MB,可以通过 -XX:ProfiledCodeHeapSize 参数进行调整。
  • 静态代码段(non-profiled segment), 保存经过全面优化的本地代码,使用寿命可能很长。 默认大小同样是 122 MB。 可以通过-XX:NonProfiledCodeHeapSize 参数进行调整。

这种新的分段结构,以不同方式处理各种类型的编译代码,整体上具有更好的性能。

例如,将已编译的短命代码和长寿代码分开,提高方法清除器的性能 - 毕竟需要扫描的内存区域变小了。

6. 小结

本文简要介绍了JVM的Code Cache内存区域。

也介绍了一些监视和诊断此内存区使用情况的方法,以及相关的优化和配置选项。


作者:铁锚
链接:https://juejin.cn/post/6985913007142354958
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

标签:Code,代码,Cache,转帖,编译,XX,JVM
From: https://www.cnblogs.com/jinanxiaolaohu/p/18130808

相关文章

  • [转帖]sysbench基准测试
    https://www.cnblogs.com/shixiuxian/p/11229822.html 一、sysbench压力测试工具简介: sysbench是一个开源的、模块化的、跨平台的多线程性能测试工具,可以用来进行CPU、内存、磁盘I/O、线程、数据库的性能测试。目前支持的数据库有MySQL、Oracle和PostgreSQL。以下操作都......
  • [leetcode 87 扰乱字符串] [剪枝搜索]
    importjava.util.HashMap;importjava.util.Map;classSolution{publicstaticvoidmain(String[]args){Solutionsolution=newSolution();booleanres=solution.isScramble("eebaacbcbcadaaedceaaacadccd","eadcaacabad......
  • AtCoder Beginner Contest 352 考试总结
    前言正常发挥。属于是\(4\)个月没搞OI,复健成功了!得分明细:ABCDEFGTotal√√√√√××1475改题明细:ABCDEFG√√√√√××第一次正式rated打AT,行吧!A.AtCoderLineProblemAtCoder铁路线有\(N\)个车站,编号为\(1......
  • AtCoder abc352
    EProblemStatementYouaregivenaweightedundirectedgraph$G$with$N$vertices,numbered$1$to$N$.Initially,$G$hasnoedges.Youwillperform$M$operationstoaddedgesto$G$.The$i$-thoperation$$(1\leqi\leqM)$$isasfollows:Youar......
  • 『Solution』Codeforces 1970B Exact Neighbours
    Easy没什么启发性,直接考虑Medium。考虑到\(a_1=0\),那么\(1\)明显直接和自己配对就行,考虑分配到一个特殊的位置\((1,1)\)。接下来考虑如果还有\(a_i=0\),那么明显\(i\)也是和自己配对,此时因为这是无关紧要的就可以离特殊的\((1,1)\)尽量远一点,也就是让\(x\)坐......
  • P3612 [USACO17JAN] Secret Cow Code S
    题目:P3612[USACO17JAN]SecretCowCodeS题面翻译奶牛正在试验秘密代码,并设计了一种方法来创建一个无限长的字符串作为其代码的一部分使用。给定一个字符串,对字符串进行一次操作(每一次正确的操作,最后一个字符都会成为新的第一个字符),然后把操作后的字符串放到操作前的字符串的......
  • vscode配置文件
    {//外观的设置//字体大小"editor.fontSize":16,//字体设置"editor.fontFamily":"'JetBrainsMonoNerdFont',Consolas,'CourierNew',monospace",//图标设置"workbench.iconTheme":"eq-mate......
  • VScode和python解释器
    VScode下载https://code.visualstudio.com/安装VScode找到下载的.exe文件,以管理员身份运行勾选我同意此协议,点击下一步修改安装路径,最好放在C盘以外的盘,点击下一步默认即可,点击下一步勾选如下图所示条目即可,点击下一步点击下一步等待安装完成下载Python解释器......
  • AtCoder Beginner Contest 351
    A-Thebottomoftheninth(abc351A)题目大意给定\(9\)个\(a_i\)和\(8\)个\(b_i\),问最后一个\(b_9\)是多少,使得\(\suma_i<\sumb_i\)。解题思路答案就是\(\suma_i-\sumb_i+1\)。神奇的代码a=sum(map(int,input().split()))b=sum(map(int,input().......
  • leetcode算法热题--最长连续序列
    题目给定一个未排序的整数数组nums,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。请你设计并实现时间复杂度为O(n)的算法解决此问题。示例1:输入:nums=[100,4,200,1,3,2]输出:4解释:最长数字连续序列是[1,2,3,4]。它的长度为4。示例2:输入:nums=......