不同操作系统下的Java程序效率

不同操作系统下的Java程序效率,java,operating-system,jvm,Java,Operating System,Jvm,我最近遇到了一个与Java相关的问题(意译): Java应用程序在操作系统a上以合理的速度运行,但在操作系统B上运行缓慢,原因是什么 程序员可以做些什么来纠正这个问题 我的回答是(我知道我错了,但我会解释我的思考过程) (1) 应用程序应该在任何具有JVM的操作系统上以大致相同的速度运行,因为应用程序是在虚拟机中运行的。只要虚拟机设计正确,它就不重要了 (2) 嗯 我的问题是:这个问题的正确答案是什么?都是关于实现的 问题在于JVM本身就是一个在主机操作系统上本机运行的程序,负责实现符合语言和库

我最近遇到了一个与Java相关的问题(意译):

  • Java应用程序在操作系统a上以合理的速度运行,但在操作系统B上运行缓慢,原因是什么

  • 程序员可以做些什么来纠正这个问题

  • 我的回答是(我知道我错了,但我会解释我的思考过程)

    (1) 应用程序应该在任何具有JVM的操作系统上以大致相同的速度运行,因为应用程序是在虚拟机中运行的。只要虚拟机设计正确,它就不重要了

    (2) 嗯


    我的问题是:这个问题的正确答案是什么?

    都是关于实现的

    问题在于JVM本身就是一个在主机操作系统上本机运行的程序,负责实现符合语言和库规范的Java库。此实现需要管理系统资源(如文件、线程、套接字等),每个操作系统可能都有自己的关于这些资源管理的“最佳实践”,这可能不一定与各种Java规范的设计保持一致。此外,操作系统本身实现了与这些系统资源的接口,其实现可能不像其他操作系统那样健壮

    例如,几年前,Linux线程实现的性能远远低于类似UNIX操作系统(例如Solaris、AIX等)上相同的POSIX线程API。因此,在Linux机器上运行的JVM将具有与Solaris机器上运行的JVM相同的功能,但Linux JVM将受到该操作系统上(当时)不太优秀的线程实现的阻碍。

    这是一个“一段字符串有多长”的问题——也就是说,OS B与OS a的行为不同有很多原因

    关于(1)你也是不对的

    例如,在我教的一个性能调优课程中,我有一个例子,其中一个相对简单的例子(很容易理解和推理)在Linux上以大约1.0的速度运行,在Mac上以1.2的速度运行,在Windows上以2.1的速度运行,在Mac上以1.5的速度运行

    也有病理病例。例如,乐高头脑风暴有(或曾经有)JVM实现。它们不执行GC,所以您基本上可以构造行为任意糟糕的示例

    您甚至不必使用不同的操作系统来查看奇怪的性能影响。我见过一些例子,其中UAT系统与生产相同,只是PROD的内核和SSD数量是HDD的两倍

    团队认为PROD中的性能会比UAT中的性能更好(或者,最坏情况下,不低于)。毕竟,PROD中的套件更好,所以不会出错,对吗

    在PROD中,性能实际上更差。额外的内核和SSD导致应用程序由I/O主导,因为SSD比HDD快。这导致吞吐量崩溃

    诊断操作系统之间性能差异的一般方法相对简单:

  • 不要以为你知道问题出在哪里。将其视为您试图解决的“未知”问题
  • 听听系统在告诉你什么。阅读它的基本重要统计数据—内存消耗、分页活动、内存页错误、线程可运行队列的大小、JVM GC活动(并确保为进程打开了所有正确的开关)
  • 默认情况下,不要接触探查器或任何其他工具。首先读取并分析系统统计数据。如果你的系统与I/O挂钩,剖析器会在某些操作系统上给出完全错误的结果,除非你真的知道自己在做什么
  • 一旦您认为您已经确定了问题(是I/O、CPU不足、GC、程序代码还是其他问题),请尝试测试您的理论
  • 如果您是对的,那么就使用细粒度的专用工具(例如,GC日志分析器,或者如果您怀疑它是应用程序代码的话,使用分析器)

  • 这将使您能够相当快地找到问题。

    您对(1)的看法是正确的。但是一个特定的VM可能在应用程序使用的特定操作系统上有一个特定功能的错误实现。尝试更改JVM实现。只要您运行的是符合Java规范的JVM,您的应用程序就会被忽略。另外-通过分析器运行它。+1线程示例也是我想到的(我想到的是Windows中的关键部分与linux中相应的锁)。除了不使用这些功能之外,我们不能做很多事情来纠正这些问题,但这几乎不是一个“解决方案”。这没有直接关系,但出于同样的原因,性能也可能因硬件而异。例如,许多java.util.concurrent类的性能都依赖于compareAndSet。在没有CAS的CPU上,必须将其转换为同步块。