我们使用Java11.0.11和-XX:ReservedCodeCacheSize=375m运行一个复杂的集群应用程序,并将相同的负载配置文件附加在24/7上,而无需重新启动。
在我们将AdoptOpenJDK jdk-11.0.11+9更新为TemurinJDK-11.0.13+8之后,我们注意到了以下更改:
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地区都保持了稳定。
Java 11.0.13 + -XX:ReservedCodeCacheSize=1024m运行稳定一周,timezone=UTC+1
我们在不同的节点上以及在一个节点上尝试了这些变化,结果总是可以重复的。
使用-XX:ReservedCodeCacheSize=375m,Linux工具显示了清除线程的高CPU使用率,该线程在1024m时完全消失。
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已满。编译器已被禁用“之类的内容。
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)仍然可以复制。
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文件。
发布于 2022-01-17 17:55:06
这是我在OpenJDK邮件列表上评论的简短摘要。我最后的评论是在2022年1月3日。
治疗方法?这听起来很愚蠢,同时也很明显:增加CodeCache空间。由于足够大的CodeCache达到稳定状态,因此禁用分段代码缓存可能是有益的。
https://stackoverflow.com/questions/70086548
复制相似问题