首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从11.0.11到11.0.13的Java更新会改变JVM代码缓存行为,并导致更多的进程cpu使用和奇怪的解析nmethods内存使用。

从11.0.11到11.0.13的Java更新会改变JVM代码缓存行为,并导致更多的进程cpu使用和奇怪的解析nmethods内存使用。
EN

Stack Overflow用户
提问于 2021-11-23 19:08:59
回答 1查看 975关注 0票数 6

我们使用Java11.0.11和-XX:ReservedCodeCacheSize=375m运行一个复杂的集群应用程序,并将相同的负载配置文件附加在24/7上,而无需重新启动。

在我们将AdoptOpenJDK jdk-11.0.11+9更新为TemurinJDK-11.0.13+8之后,我们注意到了以下更改:

  • 在具有32个vCPU、256 by内存和-Xms160G -Xmx160G的AWS -Xms160G上运行的进程CPU使用率从~ 30%增加到35%,这可能是由于JVM清除线程活动过高造成的(见下文)
  • JVM CodeHeap‘非剖析的nmethod’(C2优化代码)已被填充(used=176 MB,max=184 MB),与Java11.0.11一样,这是预期的,但是
  • 进程重新启动后不久,JVM CodeHeap 'profiled nmethods‘(C1优化代码)被填满(使用内存146 MB,最大内存184 MB ),仅15分钟就被削减到~ 40 MB,此后一直保持在这个水平(24小时)。

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

vs

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

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

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

因此,我们决定将-XX:ReservedCodeCacheSize增加一倍,达到1.024m,在过去7天中,两个CodeHeap地区都保持了稳定。

  • CodeHeap‘非剖析的nmethod’:405 MB已使用内存,405 MB已提交内存,508 MB最大内存
  • CodeHeap 'profiled nmethods':258 MB已使用内存,258 MB已提交内存,508 MB最大内存

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

我们在不同的节点上以及在一个节点上尝试了这些变化,结果总是可以重复的。

使用-XX:ReservedCodeCacheSize=375m,Linux工具显示了清除线程的高CPU使用率,该线程在1024m时完全消失。

代码语言:javascript
运行
复制
perf record -F 99 --output=perf-375m-uptime-21hours.data -ag -p <PID> sleep 60

+    4.82%     0.00%  Sweeper thread   libpthread-2.17.so                                                  [.] start_thread
+    4.82%     0.00%  Sweeper thread   libjvm.so                                                           [.] thread_native_entry
+    4.82%     0.00%  Sweeper thread   libjvm.so                                                           [.] Thread::call_run
+    4.82%     0.00%  Sweeper thread   libjvm.so                                                           [.] JavaThread::thread_main_inner
+    4.82%     0.00%  Sweeper thread   libjvm.so                                                           [.] NMethodSweeper::sweeper_loop
+    4.82%     0.00%  Sweeper thread   libjvm.so                                                           [.] NMethodSweeper::possibly_sweep
+    4.79%     0.03%  Sweeper thread   libjvm.so                                                           [.] NMethodSweeper::sweep_code_cache
+    4.24%     0.03%  Sweeper thread   libjvm.so                                                           [.] NMethodSweeper::process_compiled_method
+    4.05%     0.00%  C2 CompilerThre  libpthread-2.17.so                                                  [.] start_thread
+    4.05%     0.00%  C2 CompilerThre  libjvm.so                                                           [.] thread_native_entry
+    4.05%     0.00%  C2 CompilerThre  libjvm.so                                                           [.] Thread::call_run
+    4.05%     0.00%  C2 CompilerThre  libjvm.so                                                           [.] JavaThread::thread_main_inner
+    4.05%     0.00%  C2 CompilerThre  libjvm.so                                                           [.] CompileBroker::compiler_thread_loop
+    4.04%     0.00%  C2 CompilerThre  libjvm.so                                                           [.] CompileBroker::invoke_compiler_on_method
+    4.03%     0.00%  C2 CompilerThre  libjvm.so                                                           [.] C2Compiler::compile_method
+    4.03%     0.00%  C2 CompilerThre  libjvm.so                                                           [.] Compile::Compile
+    3.53%     0.68%  Sweeper thread   libjvm.so                                                           [.] CompiledMethod::cleanup_inline_caches_impl

因此,Java11.0.13和-XX:ReservedCodeCacheSize=1024m的CPU使用率与Java11.0.11和-XX:ReservedCodeCacheSize=375m相同或略好

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

代码语言:javascript
运行
复制
jcmd <PID> VM.log what=codecache=info,sweep*=trace decorators=time,uptime,level,tags output=codecache-sweep.log

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

这些颜色只是用来显示随着时间的变化。

寻找有趣的开始时间:codecache-sweep-375m.log.0 Regex:\[2021-11-22T10:2[5-9].+'profiled nmethods' -每分钟进行大量清扫

codecache-sweep-512m.log.0 Regex提供有趣的启动时间:\[2021-11-22T13:3[6-9].+'profiled nmethods --每分钟仍有很多次扫描。

codecache-sweep-1024m.log都很好,没什么特别的,平均每天清扫5次

请注意,代码缓存/代码堆组件中的许多更改都是在Java 11.0.12 (发行说明):Search for CodeHeap中进行的。

您能帮助我们理解CodeHeap 'profiled‘缩小到一个非常低的水平而不再增加的原因和含义吗?

更新2021-12-28

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

分析数据

更高的代码清除器调用( 11.0.13)仍然可以复制。

代码语言:javascript
运行
复制
Java 11.0.11 2h uptime, sweeper invocations:
grep -F '[codecache,sweep,start]' codecache-sweep-11.0.11_375m.log* | wc -l
14.458

Java 11.0.13 2h uptime, sweeper invocations:
grep -F '[codecache,sweep,start]' codecache-sweep-11.0.13_375m.log* | wc -l
41.901

要获得详细的统计信息,请从jcmd_compiler_codeheap_analytics_aggregate打开zip文件。

EN

回答 1

Stack Overflow用户

发布于 2022-01-17 17:55:06

这是我在OpenJDK邮件列表上评论的简短摘要。我最后的评论是在2022年1月3日。

  • 没有迹象表明观察到的行为是由bug引起的。
  • 我看到的所有日志和痕迹都显示正常运转。
  • 很有可能,在JVM升级之前,CodeHeap大小被优化到了最大值。
  • JIT代码生成中的一些小变化,例如稍微大一点的生成代码大小,已经将CodeHeap管理推向了临界点的坏一面。
  • 结果很明显:不可能达到稳定状态。有永久的代码清除和重新编译。
  • 随着时间的推移,配置方法的CodeHeap段会耗尽,因为所有的nmehtod都会变得足够热,可以在最高的优化级别上编译。

治疗方法?这听起来很愚蠢,同时也很明显:增加CodeCache空间。由于足够大的CodeCache达到稳定状态,因此禁用分段代码缓存可能是有益的。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70086548

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档