java - 为什么32位CPU/OS/Java上的Tomcat 7比64位上的Tomcat 7慢得多?

标签 java linux performance tomcat

                        Raspberry Pi3   Raspberry Pi3   Odroid C2       Odroid XU4
                        1,20 GHz        1,20 GHz        1,5 GHz         2,0 GHz
                        Debian 32 Bit   SuSE 64 Bit     Ubuntu 64 Bit   Ubuntu 32 Bit
Start Apache Tomcat     04:30,00        00:29,06        00:27,45        04:08,39
1. page (1. request)    00:50,00        00:03,91        00:03,66        00:24,75
1. page (2. request)    00:03,30        00:00,79        00:00,77        00:02,39

我正在做一个物联网项目,需要测试在java中使用tomcat作为web服务器实现的web前端在我们可能的硬件上是否“足够快”。我们需要在Raspberry Pi3Odroid C2Odroid XU4之间进行选择。PI3和C2都有64位CPU,根据它们的规格,性能略有不同,XU4只有32位CPU,理论上也应该比其他两个更快。重要的是pi3默认运行32 Bit OS即使它有64位cpu,xu4也运行32位,但是c2运行64位os,包括64位java等。
比较所有这些设备的默认设置,我们发现C2明显快于其他两个。使用我们的一些测试应用程序重启tomcat大约需要4+分钟,而不是30秒。此外,像htop这样的工具显示,大多数运行时都使用了c2的所有核心,而pi3和xu4大多只能加载一个核心。在tomcat加载后,这种巨大的性能差异是相同的,我们能够浏览我们的测试应用程序:它是~1,5秒,而仅仅浏览一些带有css/js的页面是4到5,5秒。
虽然pi3的默认操作系统只有32位,但我们成功地安装了一个特殊的64位suse发行版。猜猜怎么回事?现在的性能更接近我们在C2上看到的,在许多测试中几乎相同,尽管PI3的时钟只有1,2而C2的1,5 GHz。特别有趣的是,现在所有的PI3核心大部分时间都在负载下,所以整体行为非常像现在的C2。
因此,通过只切换到64位操作系统、Java等,我们看到了性能的显著提高。其他一切都一样,相同的测试应用程序,tomcat等等,没有超频,没有其他存储或其他。怎么会这样?是什么导致了这种戏剧性的进步?
与32位操作系统相比,64位操作系统的所有核心设备都处于负载下。但是,如果linux内核调度器在32位或64位上运行得这么多,它为什么要在意呢?
如果没有,而且差异来自java,为什么/怎么会这样?在这样一个简单的测试中,32位和64位jvm的性能不应该几乎相同吗?难道这两者不应该特别地对核心施加几乎相同的负载,而不会表现出那么不同吗?操作系统的架构不应该影响jvm中使用了多少线程,jvm主要由tomcat和我们的测试应用程序控制,因此没有改变。根据我所读到的关于32 vs. 64 Bit Java性能的内容,在我的用例中,差异应该可以忽略不计。另外,其他better performance of a 64 Bit JVM的用户似乎没有像我看到的那样有4到5的因数,而且各个内核的cpu负载差异也没有解释清楚。
我们的测试不受i/o限制,我们不分配太多内存,也不使用太多线程,它几乎是严格的cpu,只编译java类和发布html、css和js。但是根据32/64位和非常不同的性能结果,我们在内核上看到非常不同的负载。
我的一位同事说,他在某个地方读到,Java在内部只使用64位值,因此在32位CPU/OS上,需要更多的周期来处理相同的事情。我想他的来源并不意味着所有的东西,只是像对象那样引用/指向内存的指针。但我不能相信,一个32位的JVM在内部真正使用64位指针没有理由,特别是如果甚至优化,如compressed oops存在。但可能是一个解释,所以有什么想法吗?
如果有兴趣的话,32位操作系统上的包都有“armhf”作为架构,而64位操作系统上的包是“arm64”。我认为这可能会影响Java的构建,也许真的是出于某种奇怪的原因使用64位指针?
java始终是openjdk 8,与os一样的体系结构,并且与os的包管理器一样通用。带有suse的pi3有1.8u144,ub为32位和64位安装提供了1.8u131,都是服务器vm。另外,Linux内核是不同的,例如SUSE的PI3与UB的C2和XU4:PI3有一些当前的4.x,C2有一些旧的3.14,XU4也有一些当前的4.9。
那么,有什么不同之处吗?谢谢!

最佳答案

你已经告诉过你从标准包中安装了openjdk 8。
openjdk 8从来没有为arm 32优化过构建(至少在debian和ubuntu上是这样)。默认包是从“zero”端口构建的,该端口甚至没有jit编译器。

root@localhost:~# java -server -version
openjdk version "1.8.0_131"
OpenJDK Runtime Environment (build 1.8.0_131-8u131-b11-1~bpo8+1-b11)
OpenJDK Zero VM (build 25.131-b11, interpreted mode)
        ^^^^^^^                    ^^^^^^^^^^^^^^^^

尝试从Java SE downloads page手动安装Oracle JDK。
它内部有一个优化的热点jvm。而且它确实工作得更快。
root@localhost:~# /usr/java/jdk1.8.0_131/bin/java -server -version
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) Server VM (build 25.131-b11, mixed mode)
     ^^^^^^^^^^^^^^^^^^^^^                    ^^^^^^^^^^

相比之下,hotspot jvm的aarch64端口长期以来都是openjdk的一部分。因此,在64位操作系统上,默认的openjdk包附带hotspot jvm,其中包括一个优化的jit编译器。

关于java - 为什么32位CPU/OS/Java上的Tomcat 7比64位上的Tomcat 7慢得多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46694569/

相关文章:

java - 如何生成带有双反斜杠或正斜杠分隔符的目录路径?

java - 使用 iFolderLayout 的 Eclipse RCP 中的隐藏 View 部分

java - 在 ARM 上使用 BlueCove-DBus。 Linux 上 C 库和 Java 代码 (JNI) 之间的链接器错误

c - 我必须使用哪些命令才能通过 I²C 使用 SSD1306?

javascript - CDN 上有哪些著名的 JavaScript 库,URL 是什么?

performance - 什么导致 Oracle tkprof 文件中 CPU 时间和耗时之间存在差异

java - If 子句中的对象特定行为

java - 为什么我得到 `incompatible types error` ?

linux - 使用 multipart/form-data 和 JSON curl 帖子

performance - JMeter:更多 HTTP 请求导致性能提高?