当前位置:首页 > 公众号精选 > Linux阅码场
[导读]编者按:目前许多公司同时使用x86和AArch642种主流的服务器。这两种环境的算力相当,内存相同的情况下:相同版本的JVM和Java应用,相同的JVM参数,应用性能在不同的平台中表现相差30%,x86远好于AArch64平台。本文分析了一个应用在AArch64平台上性能下降的例...

编者按:目前许多公司同时使用 x86 和 AArch64 2 种主流的服务器。这两种环境的算力相当,内存相同的情况下:相同版本的 JVM 和 Java 应用,相同的 JVM 参数,应用性能在不同的平台中表现相差 30%,x86 远好于 AArch64 平台。本文分析了一个应用在 AArch64 平台上性能下降的例子,发现 JVM 的 CodeCache 大小是引起这个性能问题的根源,进而研究什么导致了不同平台上 CodeCache 大小的不同。最后笔者给出了不同平台中该如何设置参数规避该问题。希望本文能给读者一些启示:当使用不同的硬件平台时需要关注底层硬件对于上层应用的影响。

业务在 x86 和 AArch64 上同时部署时(相同的 JDK 和 Java 应用版本),发现 AArch64 平台性能下降严重问题。进一步查看日志,发现在 AArch64 平台中偶有如下情况:

这代表 JVM 中的 CodeCache 满了,导致编译停止,未编译的方法只能解释执行,进而严重影响应用性能。那什么是 CodeCache

CodeCache 是什么

简单来说,CodeCache 用于存放编译后的方法,主要分为三部分:

  1. Non-nmethods:包括运行时 Stub,Adapter 等;
  2. Profiled nmethod:包括会采集信息的方法,即分层编译中第 2、3 层的方法;
  3. Non-Profiled nmethods:包括不采集信息的方法,即分层编译中第 1、4 层的方法,也包括 JNI 的方法。
注:分层编译指的是 JVM 同时存在 C1 和 C2 两种编译器,C1 做一些简单的编译优化,耗时较短,C2 做更多复杂的编译优化,性能较好,编译耗时较多。分层编译的触发在 JVM 内会根据相应的条件进行触发,关于更多分层编译相关知识可以参考相关资料 [1]。

在 JDK 9 之后 [2],这些会分配到不同的区域(使用不同区域的优点:查找、回收等),JDK 8 中会分配到同一块区域。

JVM 平时会清理一些不可达的方法,例如由于退优化等产生的死方法,另外 UseCodeCacheFlushing 选项(默认开启),还会清理较老以及执行较少的方法。一旦 CodeCache 满了之后,会停止编译,直到 CodeCache 有空间,若关闭了 UseCodeCacheFlushing 选项,则会直接永久停止编译。

不同的 JVM 版本以及不同的参数,默认的 CodeCache 大小不同。JDK 11 中默认参数下 CodeCache 大小为 240M,若想获取(确认)默认情况下的 CodeCache 大小,建议使用 - XX: PrintFlagsFinal 选项获取 ReservedCodeCache 的大小。

CodeCache 大小主要通过以下选项调节:

OptionDescription
InitialCodeCacheSize初始的 CodeCache 大小(单位字节)
ReservedCodeCacheSize预留的 CodeCache 大小,即最大CodeCache 大小(单位字节)
CodeCacheExpansionSizeCodeCache 每次扩展大小(单位字节)
使用–XX: PrintCodeCache 选项可以打印应用使用的 CodeCache 情况,如下:

其中 max_used 表示应用中使用到的 CodeCache 大小,据此可以设置合适的 ReservedCodeCacheSize 值。

AArch64 vs x86_64

我们都知道 AArch64 和 x86 分别为 RISC 和 CISC 架构,因此代码密度方面存在一定差异,在这篇文章 [3] 中比较了不同指令集下手写汇编的大小,可以看到 AArch64 的代码密度是 RISC 架构中较优的,但相比 x86_64 仍稍差些(其中 RISC 最差,m68k 最好)。

另外笔者选用业界通用的 java 测试套 dacapo[4] 比较 AArch64 和 x86_64 下 CodeCache 占用的大小。

可以看到,在 AArch64 架构下,CodeCache 均比 x86_64 要大,但根据不同场景,大小差距不同,在 5%-20% 之间。因此在我们发现相同应用在 x86 和 AArch64 上时,CodeCache 大小需要进行相应的调节。

除此之外,还需要注意 InlineSmallCode 选项,JVM 只会 inline 代码体积比该值小的方法。JVM 通过 inline 可以触发更多的优化,因此 inline 对于性能提升也很重要。在 JDK 11 中,InlineSmallCode 在 x86 下的默认值为 2000 字节,在 AArch64 下的默认值为 2500 字节。而 JDK 8 中,InlineSmallCodex86 和 AArch64 下默认值均为 2000 字节。因此建议迁移时也相应修改 InlineSmallCode 的值。业务通过对 CodeCache 相关参数的调整,达到助力 JIT 的最佳编译效果。

后记

如果遇到相关技术问题(包括不限于毕昇 JDK),可以进入毕昇 JDK 社区查找相关资源(点击原文进入官网),包括二进制下载、代码仓库、使用教学、安装、学习资料等。毕昇 JDK 社区每双周周二举行技术例会,同时有一个技术交流群讨论 GCC、LLVM、JDK 和 V8 等相关编译技术,感兴趣的同学可以添加如下微信小助手,回复 Compiler 入群。

rc="https://img.21ic.com/weixin/tr/2021-09/23/476wvino842.png">

参考

[1]http://cr.openjdk.java.net/~thartmann/talks/2017-hotspot_under_the_hood.pdf

[2]https://bugs.openjdk.java.net/browse/jdk-8015774

[3]http://web.eece.maine.edu/~vweaver/papers/iccd09/ll_document.pdf

[4]http://dacapobench.org/


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

5月7日消息,宝德计算(PowerLeader)举办发布会,正式推出“Powerstar”(暴芯)处理器,基于x86架构,看起来和Intel 11代酷睿如出一辙。

关键字: x86 处理器 宝德计算

2月23日晚,国产CPU公司海光信息发布了2022全年财报预告,公司实现营业收入51.25亿元,同比增长121.83%;实现归属于母公司所有者的净利润8.02亿元,同比增长145.18%。

关键字: x86 ARM RISC-V

据业内信息报道,全球 x86 处理器市场在 2022 年 Q4 季度迎来了近 30 年来最大季度跌幅以及年度跌幅。

关键字: x86 处理器

前几年,在芯片领域中谈到架构无外乎是x86、ARM两大架构。这两大架构分工明确,x86占据了PC市场95%以上的市场,ARM则垄断手机市场。看似二者分境而治,实则业界对于二者谁主宰未来的市场的讨论一直进行着。

关键字: RISC - V x86 ARM

11月16日,龙芯中科在南京举办2022年信息技术自主创新高峰论坛。

关键字: 龙芯 7nm CPU x86

龙芯中科官方宣布,与软通动力控股公司鸿湖万联共同完成了OpenHarmony操作系统(开放版“鸿蒙”)与龙芯2K1000LA处理器的适配,搭载龙芯2K1000LA的“乘风1000”开发板也荣获了OpenHarmony生态...

关键字: 龙芯中科 ARM x86

北京时间7月14日早间消息,据报道,Alphabet旗下谷歌云部门当地时间周三宣布,他们将开始采用基于ARM技术的芯片,成为又一个加入这一转型浪潮的大型科技公司,从而给英特尔和AMD带来更大的压力。

关键字: 谷歌云 x86 ARM

据龙芯中科官方消息,近日,DMTF(分布式管理任务组)旗下的SMBIOS规范正式支持龙芯自研的龙架构(LoongArch)。

关键字: 龙芯 7nm AMD x86

由于AMD及Intel等公司退出俄罗斯,导致该国无法使用欧美公司的芯片,只能转向自研处理器,不仅超算要用俄罗斯公司的CPU,现在ATM机也要使用自研的Elbrus处理器,虽然最高8核,不过性能大概是10年前的x86水平。

关键字: 俄罗斯 x86 处理器

随着MIPS的倒下,RISC-V已悄然成为世界第三大处理器架构,并对x86和ARM虎视眈眈。

关键字: x86 ARM RISC-V
关闭
关闭