转载:相同版本的JVM和Java应用,在 x86 和AArch64 平台性能相差30%
没有仔细分析。
业务在 x86 和 AArch64 上同时部署时(相同的 JDK 和 Java 应用版本),发现 AArch64 平台性能下降严重问题。进一步查看日志,发现在 AArch64 平台中偶有如下情况:
这代表 JVM 中的 CodeCache
满了,导致编译停止,未编译的方法只能解释执行,进而严重影响应用性能。那什么是 CodeCache
?
CodeCache 是什么
简单来说,CodeCache
用于存放编译后的方法,主要分为三部分:
Non-nmethods
:包括运行时 Stub,Adapter 等;Profiled nmethod
:包括会采集信息的方法,即分层编译中第 2、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
大小主要通过以下选项调节:
Option | Description |
---|---|
InitialCodeCacheSize | 初始的 CodeCache 大小(单位字节) |
ReservedCodeCacheSize | 预留的 CodeCache 大小,即最大CodeCache 大小(单位字节) |
CodeCacheExpansionSize | CodeCache 每次扩展大小(单位字节) |
使用–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 中,InlineSmallCode
在 x86 和 AArch64 下默认值均为 2000 字节。因此建议迁移时也相应修改 InlineSmallCode
的值。业务通过对 CodeCache
相关参数的调整,达到助力 JIT 的最佳编译效果。
后记
如果遇到相关技术问题(包括不限于毕昇 JDK),可以进入毕昇 JDK 社区查找相关资源(点击原文进入官网),包括二进制下载、代码仓库、使用教学、安装、学习资料等。毕昇 JDK 社区每双周周二举行技术例会,同时有一个技术交流群讨论 GCC、LLVM、JDK 和 V8 等相关编译技术,感兴趣的同学可以添加如下微信小助手,回复 Compiler 入群。
转载:相同版本的JVM和Java应用,在 x86 和AArch64 平台性能相差30%相关推荐
- Java三大版本及 JVM JDK JRE 及 SDK API
目录 1.三大版本 2. JDK JRE JVM 3. SDK API 1.三大版本 JavaSE: 标准版,整个Java的基础及核心,主要用于开发桌面程序及控制台程序. JavaME: 移动版,基本 ...
- JVM学习1:JVM和Java体系结构
JVM和Java体系结构 计算机本身是不识别高级语言的,这个大家应该都知道,我们的Java.C.Python这些代码都要执行下面的一个流程 随着Java7发布以后,Java虚拟机可以根据JSR-292 ...
- 一、JVM及Java体系结构
文章目录 1.跨平台的语言Java和跨语言的平台JVM (1)Java生态圈 (2)Java跨平台的语言 (3)JVM:跨语言的平台 2.字节码与多语言混合编程 (1)字节码 (2)多语言混合编程 3 ...
- JVM与Java的体系结构(JVM入门知识体系总结)
写在前面:博主是一位普普通通的19届双非软工在读生,平时最大的爱好就是听听歌,逛逛B站.博主很喜欢的一句话花开堪折直须折,莫待无花空折枝:博主的理解是头一次为人,就应该做自己想做的事,做自己不后悔的事 ...
- jvm对于java的意义_谈谈对JVM的理解
JVM可谓是学习JAVA基础中的基础了,但仍有不少同学对JVM概念还是比较模糊,甚至没有听说过,对java的理解也只是在基础语法 层面,本文就将对JVM进行初步介绍,因篇幅所限,只能介绍JVM基础,如 ...
- java线程堆栈_深入JVM剖析Java的线程堆栈
在这篇文章里我将教会你如何分析JVM的线程堆栈以及如何从堆栈信息中找出问题的根因.在我看来线程堆栈分析技术是Java EE产品支持工程师所必须掌握的一门技术.在线程堆栈中存储的信息,通常远超出你的想象 ...
- 第 1 章 JVM 和 Java 体系架构
第 1 章 JVM 和 Java 体系架构 1.JVM 前言 作为Java工程师的你曾被伤害过吗?你是否也遇到过这些问题? 运行着的线上系统突然卡死,系统无法访问,甚至直接OOM! 想解决线上JVM ...
- 深入理解JVM:Java语言与JVM关系
在那个电闪雷鸣,群鸟环绕的夜晚,一个不为人知的语言Oak诞生了,此时正值1991年4月份,气温舒适,百花齐放.然而Oak的诞生并没有得到人们的关注,直到1995年5月23号,Oak决定正是更名为Jav ...
- JVM和Java体系架构
前言 你是否也遇到过这些问题? 运行着的线上系统突然卡死,系统无法访问,甚至直接OOM! 想解决线上JVM GC问题,但却无从下手. 新项目上线,对各种JVM参数设置一脸茫然,直接默认吧然后就JJ了. ...
- Java 版本变更列表 (Java SE 8 ~ Java SE 18 )
java 版本变更列表 Java SE 8 Java SE 9 Java SE 10 Java SE 11 Java SE 12 Java SE 13 Java SE 14 Java SE 15 Ja ...
最新文章
- Django 视图函数
- jQuery1.8 css模块评析
- matlab loopcount,求助一个数值积分问题,用matlab的quadgk函数来计算,谢谢!
- 优化Linux下的内核TCP参数来提高服务器负载能力
- Win7有多条隧道适配器(isatap、teredo、6to4)的原因及关闭方法
- 为什么要实施服务器虚拟化
- php 获取京东交易账号,PHP爬虫爬取京东列表
- EasyMock 简介
- 手把手教你强化学习 (五) 为什么需要值迭代和策略迭代
- c语言中fac函数杨辉三角,C语言常用算法
- 如何在有线路由器下接无线路由
- warning: implicit declaration of function ‘typeof’
- FPGA芯片行业科普
- EMD/EEMD 经验模态分解/集合经验模态分解
- 文本特征提取和向量化
- pdf用什么软件打开
- from表单的重置按钮(reset)不能重置隐藏input框的值
- 小胡网创:读书和赚钱是一个人一生最好的修行
- [Unity] 二维洞穴地图随机生成
- Sketch设置透明背景
热门文章
- sympy模块解指数方程
- hadoop 压缩工具 比较
- php如何使用memcached,PHP如何使用Memcached_PHP
- OpenCV读取网络摄像头视频并保存到本地
- php算法复杂度,php的几个经典排序算法及时间复杂度和耗时​
- git 客户端_GEE 学习笔记 3: 客户端连接远程服务器的 Jupyter ( git 作为本地工具)
- gps python获取图片坐标_女朋友会 Python 是多么可怕的一件事!
- php workman实现socket服务及客户端连接
- Spring的核心思想,依赖注入
- kafka+多线程实现案例+Callable