问题标签 [jvm-codecache]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
3561 浏览

java - 为什么java代码缓存大小在增长?

我有这个基本程序,它什么都不做,只是坐在那里等待输入:

当我运行这个时:

我通过 JConsole 连接以查看:

代码缓存增加

这仅仅是因为最初正在编译核心 java 字节码吗?当进程没有做任何事情时,代码缓存如何增加?

当我有这个版本(它使用Thread.sleep)时:

我明白了:

代码缓存增加

那么……为什么会这样?

PS这是输出java -version

0 投票
2 回答
1585 浏览

java - 如何使用 jstat 获取非堆“代码缓存”详细信息

我想从我的 windows 机器上找到在 windows 上运行的远程 JVM (JDK 8)的非堆内存 代码缓存详细信息。我可以使用jconsole获取详细信息。但是,我需要的是使用jstat命令获取值。GUI 监控工具不符合我的目的。谢谢

0 投票
1 回答
472 浏览

java - 空闲后的 JVM JIT 去优化

我主要使用 Java 编写宠物项目,这些项目大部分时间都是空闲的。在空闲数小时/天后,响应时间增加到秒(最多 10 秒),然后慢慢减少回 200-300 毫秒。

据我了解,发生这种情况是因为 JIT去优化(优化的代码被标记为僵尸,被删除然后再次编译)。

除非代码缓存已满,否则有什么方法可以禁止 JVM 去​​优化代码?Java 9 的 AOT 看起来是这种情况下的最佳解决方案,但我仍然没有设法使其工作。

UPD:和往常一样,正确的解决方案是显而易见的。看起来问题实际上是由交换引起的。尽管有 12 GB 的内存,其中 6 个是空闲的,但一段时间后,每个 JVM 的内存中大约有 100 MB 被交换到了 HDD。

尽管如此,@apangin 的回答对于遇到同样情况的其他人来说可能很有用,所以我把这个问题留在这里。谢谢大家!

0 投票
0 回答
248 浏览

jvm - JVM 的 JIT CodeCache 什么时候回收?有人知道吗?

我最近遇到了一个 JIT 错误:Java HotSpot(TM) 64-Bit Server VM warning: CodeCache is full. Compiler has been disabled.这导致我的应用程序运行缓慢。我的JDK版本是Oracle JDK1.7.0_79。默认 CodeCache 大小为 48m,我使用 -XX:ReservedCodeCacheSize=256M 修改了大小。但是不知道 CodeCache 什么时候被回收的。有人知道吗?

0 投票
1 回答
952 浏览

java - JVM 编译时间与代码缓存

我一直在对我的应用程序进行基准测试并使用 JMC 对其进行分析。我注意到在负载下,它会执行相当多的 JIT 编译。如果我每秒发送大量事务,编译时间就会激增。编译时间总是随着对应用程序的任何重负载测试成比例地增长。

我还观察到代码缓存也在缓慢上升。所以我决定将 Code Cache 预留提高到 500MB 进行测试。坏动作!现在它花费更多的时间来执行 JIT。

然后我通过-XX:-UseCodeCacheFlushing. 但是,我注意到峰值代码缓存使用量大于当前大小。这让我想到了几个问题:

在此处输入图像描述

  1. JVM 是否尝试缓存每个 JIT 编译?
  2. 为什么即使我禁用了刷新,峰值代码缓存大小仍大于当前大小?
  3. 函数结束后是否有“临时”编译代码自动删除?
0 投票
2 回答
407 浏览

tomcat - 目前是否有显示 JVM 代码缓存使用情况的 Linux 命令行?

我们在 Tomcat 7 上运行的一个 Java 应用程序中收到了一些错误。我正在寻找一个可以随时向我们显示代码缓存值的命令行。有没有类似 jstat 的命令可以打印出 Code Cache 的值?

谢谢!

0 投票
1 回答
220 浏览

java - Java 9+ 分段代码缓存是否需要 Java 9+ 编译?

我们的软件仍然支持使用 JVM 8 部署的客户端,因此我们仍在使用 Java 8 进行编译。我正在尝试了解 Java 9 中引入的分段代码缓存JEP197是否适用于较旧的编译 - 或者还需要源代码在 Java 9+ 上编译。

很多在线资源都描述了它有多棒,但我找不到一个明确的错误,Java 8 代码是否可以利用这种能力。

分段代码缓存是否适用于 Java 8 编译代码?

0 投票
2 回答
94 浏览

java - 我可以让类加载器动态查找 Java 类吗?

我想根据运行时条件动态选择不同的类实现。假设我有一个具有完全限定类名称 C 的类。我正在运行的系统可能有许多 C 类的定义,每个定义都在自己的 jar 中。我有一个运行时条件(保存在 ThreadLocal 中),它告诉应该选择哪个定义。

有人在评论中要求我澄清原始要求,因此我将尽我所能澄清要求。有多个团队编写软件来为这个系统做出贡献——就像许多独立模块中的 4000 个类一样。更重要的是,它们可以随着时间而改变。它们目前在单独的 JVM 中运行,因此类重叠没有问题。现在我们正在考虑在同一个 JVM 中运行它们,同时在同一个 JVM 上运行多个版本;使用哪个特定的实现集由 ThreadLocal 区分。所以最初的问题是如何允许一个线程一次运行一组实现,另一次运行另一个。

我有一个当前使用 OpenJDK 8 的 tomcat 应用程序。

我相信我可以编写一个自定义的 ClassLoader 来操纵类路径以根据 ThreadLocal 以不同的方式选择 C ​​的定义。但我担心结果会被缓存在某个地方,比如 JVM Code Cache。除非我也可以覆盖该行为,否则下次需要该类时,运行时条件可能已更改并且缓存中的版本将是错误的。

有什么办法可以做我需要做的吗?

0 投票
1 回答
251 浏览

java - 从 11.0.11 到 11.0.13 的 Java 更新更改了 JVM 代码缓存行为并导致更多进程 cpu 使用和奇怪的配置文件 nmethods 内存使用

我们使用 Java 11.0.11 和 -XX:ReservedCodeCacheSize=375m 运行一个复杂的集群应用程序,并 24/7 全天候附加相同的负载配置文件,无需重新启动。

在我们将 AdoptOpenJDK jdk-11.0.11+9 更新为 Temurin jdk-11.0.13+8 后,两者都使用 -XX:ReservedCodeCacheSize=375m 且我们的应用程序中没有任何代码更改,只是更新了 Java,我们注意到以下更改:

  • 在具有 32 个 vCPU、256GB RAM 和 -Xms160G -Xmx160G 的 AWS r5.8xlarge上运行的进程 CPU 使用率从 ~ 30% 增加到 ~ 35% ,这可能是由高 JVM Sweeper 线程活动引起的(见下文)
  • JVM CodeHeap 'non-profiled nmethods'(C2 优化代码)已填满(使用 = 176 MB,最大 = 184 MB)与 Java 11.0.11 一样,这是预期的但
  • JVM CodeHeap 'profiled nmethods'(C1 优化代码)在进程重新启动后不久被填满(146 MB 已用内存,184 MB 最大内存),并在 15 分钟后减少到 ~ 40 MB,从那时起一直保持在这个水平( 24小时)

Java 11.0.13 + -XX:ReservedCodeCacheSize=375m,时区=UTC+1 Java 11.0.13 + -XX:ReservedCodeCacheSize=375m

对比

Java 11.0.11 + -XX:ReservedCodeCacheSize=375m,时区=UTC+1 Java 11.0.11 + -XX:ReservedCodeCacheSize=375m

下一步是将 -XX:ReservedCodeCacheSize 增加到 512m,但大约 3 小时后,JVM CodeHeap 'profiled nmethods'(C1 优化代码)再次减少到大约 50 MB,甚至随着时间的推移进一步减少

Java 11.0.13 + -XX:ReservedCodeCacheSize=512m,时区=UTC+1 Java 11.0.13 + -XX:ReservedCodeCacheSize=512m

因此,我们决定将 -XX:ReservedCodeCacheSize 加倍至 1024m,并且在过去 7 天中,两个 CodeHeap 区域都保持稳定

  • CodeHeap 'non-profiled nmethods':405 MB 已用内存,405 MB 已提交内存,508 MB 最大内存
  • CodeHeap 'profiled nmethods':258 MB 已用内存,258 MB 已提交内存,508 MB 最大内存

Java 11.0.13 + -XX:ReservedCodeCacheSize=1024m 稳定运行一周,时区=UTC+1 Java 11.0.13 + -XX:ReservedCodeCacheSize=1024m

我们在不同节点和一个节点上尝试了这些更改,结果始终是可重现的。


使用 -XX:ReservedCodeCacheSize=375m,Linux perf 工具显示 Sweeper 线程的 CPU 使用率很高,1024m 时完全消失。

因此,Java 11.0.13 和 -XX:ReservedCodeCacheSize=1024m 的 CPU 使用率与 Java 11.0.11 和 -XX:ReservedCodeCacheSize=375m 相同或略好


在我们的调查过程中,没有打印出有用的日志行,例如,我们希望看到类似“CodeCache 已满。编译器已被禁用”之类的内容。

图片中的所有图表均使用时区 UTC+1。日志文件中的所有时间戳都是 UTC+0。

颜色只是为了显示随时间的变化。

codecache-sweep-375m.log.0 有趣的开始时间的正则表达式:\[2021-11-22T10:2[5-9].+'profiled nmethods'- 每分钟扫描很多 codecache-sweep-375m.log.0 图片

codecache-sweep-512m.log.0 有趣的开始时间的正则表达式:\[2021-11-22T13:3[6-9].+'profiled nmethods- 每分钟仍然有很多扫描。 codecache-sweep-512m.log.0 图片

codecache-sweep-1024m.log 一切正常,没什么特别的,平均每天 5 次扫描 在此处输入图像描述


请注意,在 Java 11.0.12(发行说明)中对代码缓存/代码堆组件进行了很多更改:搜索CodeHeap

您能否帮助我们理解 CodeHeap 'profiled nmethods' 缩小到非常低的水平并且不再增加的原因和含义?


更新 2021-12-28

使用 -XX:ReservedCodeCacheSize=375m 重新运行 11.0.11 和 11.0.13,jcmd <pid> Compiler.CodeHeap_Analytics aggregate每 5 秒为 OpenJDK 团队收集更多数据。

Java 11.0.11 与 11.0.13

带有日志和 CodeHeap_Analytics 数据的 zip

仍然可以重现更高级别的代码扫描程序调用(使用 11.0.13)。

有关详细统计信息,请从zip打开 jcmd_compiler_codeheap_analytics_aggregate 文件。

文本差异 jcmd_compiler_codeheap_analytics_aggregate_2021-12-28-191001.txt 与 jcmd_compiler_codeheap_analytics_aggregate_2021-12-28-191000.txt