面向Java开发人员的JVM参数指南

image.png
导读:通过理解和使用 JVM 以及 JVM 参数,开发人员和最终用户都可以诊断故障并且提高 Java 应用程序的性能。

本文字数:5847,阅读时长大约: 7分钟
image.png

通过理解和使用 JVM 以及 JVM 参数,开发人员和最终用户都可以诊断故障并且提高 Java 应用程序的性能。

通过理解和使用 JVM 以及 JVM 参数,开发人员和最终用户都可以诊断故障并且提高 Java 应用程序的性能。

当你在编写源代码时,你是在编写人类可以阅读的代码。在将代码编译成机器语言之前,计算机无法执行它。机器语言是一个通用术语,指的是特定机器所需的任意数量的语言。通常,如果你在 Linux 上编译代码,它只能 Linux 上运行;如果你在 Windows 上编译代码,它就只在 Windows 上运行。但是,Java 是不同的,它并不以真实的机器为目标,而是面向 Java 虚拟机 (Java Virtual Machine) (JVM)。因此,它可以在任何机器上运行。

Java 源代码被编译成 字节码 (bytecode) ,然后由安装在计算机上的 JVM 运行。JVM 是一个执行引擎,但我们通常不会直接与它交互。它在后台静默运行,替我们处理 Java 字节码。大多数人不需要考虑,甚至也不需要知道 JVM。但是,了解它的工作原理是对我们来说是非常有用的,因为这会有助于我们调试和优化 Java 代码。例如:

◈ 在生产环境中,你发现已经部署的应用程序可能需要提升性能。

◈ 如果你写的应用程序出错了,开发人员和最终用户都可以选择对问题进行调试。

◈ 如果你想了解关于 JDK(即 Java 开发工具包 (Java Development Kit) ,用于开发/运行 Java 应用程序)的详细信息,你可以通过查询 JVM 来获取。

本文介绍了一些基础的 JVM 参数,希望在这些场景中可以提供帮助。

image.png

JVM 参数

(图源:Jayashree Huttanagoudar,CC BY-SA 4.0)

JVM、JDK 和 JRE 有什么不同?

Java 有许多 J 开头的缩略词,包括 JVM、JDK 和 JRE。

◈ Java 开发工具包 (Java Development Kit) (JDK)可供需要在代码中使用开发库的程序员使用。

◈ Java 运行时环境 (Java Runtime Environment) (JRE)可供想运行 Java 应用程序的人使用。

◈ Java 虚拟机 (Java Virtual Machine) (JVM)是运行 Java 字节码的组件。

JDK 同时包含 JRE 和 JVM,但有些 Java 发行版提供了包含 JRE(包括 JVM)的替代下载。

image.png

JDK

(图源:Jayashree Huttanagoudar,CC BY-SA 4.0)

Java 是开源的,因此,许多不同的公司都会构建和发行他们自己的 JDK 发行版。你可以在系统上安装多个 JDK,这会对你参与或者运行不同的 Java 项目时很有帮助,因为其中一些项目可能使用旧版本的 JDK。

你可以使用 alternatives 命令,来查看 Linux 系统上的 JDK 列表:

  1. $ alternatives --config java

  2. Thereare 2programs that provide java.

  3. SelectionCommand

  4. *+1java-11-openjdk.x86_64 (/usr/lib/jvm/java-11-openjdk-11.0.13.0.8-2.fc35.x86_64/bin/java)

  5. 2java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.312.b07-2.fc35.x86_64/jre/bin/java)

  6. Enterto keep the current selection[+],ortype selection number:

$ alternatives --config java

Thereare 2programs that provide java.

SelectionCommand

*+1java-11-openjdk.x86_64 (/usr/lib/jvm/java-11-openjdk-11.0.13.0.8-2.fc35.x86_64/bin/java)

2java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.312.b07-2.fc35.x86_64/jre/bin/java)

Enterto keep the current selection[+],ortype selection number:

如果想要在可用的 JDK 之间进行切换,请再次执行该命令:

  1. $ sudoalternatives --config java

或者可以使用 SDKMan 🔗 opensource.com ,它可以下载、更新和管理系统中的所有 JDK。

什么是 JVM 调优?

JVM 调优指的是,通过调整 JVM 参数,来提高 Java 应用程序性能的过程,它还有助于诊断应用程序的故障。

通常情况下,在调试之前需要考虑以下几点:

◈ 成本:有时改进运行代码的硬件可以提高应用程序的性能。这可能看起来像是在“作弊”,但请考虑你愿意花多少时间调整 JVM 参数。有时应用程序需要更多的内存来执行所需的功能,而这点是任何软件技术都无法改变的。

◈ 期望结果:长期来看,稳定性比性能更重要。如果你的调优对稳定性产生了影响,那么谨慎地选择你的调优参数可能会更好。

◈ 底层问题:有时,问题可能是主机操作系统的底层问题。那么,在调整 JVM 之前,请确保 JVM 平台按预期工作。

◈ 内存泄漏:如果你在使用垃圾回收(GC)调优参数,那么,应用程序代码中很可能会存在需要修复的内存泄漏。

参数类型

JVM 参数可以分为以下三类:标准参数、非标准参数和高级选项。

标准参数

所有的 JVM 实现都支持标准参数,在终端执行 java 命令来查看标准参数列表:

  1. $ java

  2. Usage:java [options][args…]

  3. (to execute a class)

  4. orjava [options]-jar [args…]

  5. (to execute a jar file)

  6. whereoptions include:

  7. -cp<classsearch path of directories andzip/jar files>

  8. -classpath <classandzip/jar files>

  9. –class-path <classandzip/jar files>

  10. A :separated listof directories,JAR archives,

  11. andZIP archives to search forclassfiles.

  12. –enable-preview

  13. allow classes to depend on preview features of thisrelease

  14. Tospecify an argument fora longoption,you can use–=or

  15. –.

$ java

whereoptions include:

-cp<classsearch path of directories andzip/jar files>

-classpath <classandzip/jar files>

–class-path <classsearch path of directories andzip/jar files>

A :separated listof directories,JAR archives,

andZIP archives to search forclassfiles.

–enable-preview

allow classes to depend on preview features of thisrelease

Tospecify an argument fora longoption,you can use–=or

–.

这些是所有 JVM 都会包含的标准参数,你可以像使用任何 命令行选项 🔗 opensource.com 一样安全地使用它们。例如,要验证配置的命令选项,创建 VM 并加载主类而不执行主类,请使用:

  1. $ java --dry-run

非标准参数

非标准选项以 -X 开头。这些是通用的,并且特定于 JVM 的特定实现。要列出这些参数,请输入:

  1. $ java -X

  2. -Xbatchdisable background compilation

  3. -Xbootclasspath/a:<directories andzip/jar files separated by :>

  4. append to endof bootstrap classpath

  5. -Xinternalversion

  6. displays moredetailed JVM version information than the

  7. -version option

  8. -Xloggc:log GC status to a filewithtimestamps

  9. […]

$ java -X

-Xbatchdisable background compilation

-Xbootclasspath/a:<directories andzip/jar files separated by :>

append to endof bootstrap classpath

-Xinternalversion

displays moredetailed JVM version information than the

-version option

-Xloggc:log GC status to a filewithtimestamps

在这些参数可能会不经通知就发生变化。而且,并非所有 JVM 实现都支持这些参数。

微软构建的 JVM 可能与 RedHat 构建的 JVM 有不同的参数,诸如此类。

要获取详细的 JVM 版本信息,请使用如下命令:

  1. $ java -Xinternalversion–version

  2. OpenJDK64-BitServerVM (11.0.13+8)forlinux-amd64 JRE (11.0.13+8),built on Nov8202100:00:00by "mockbuild"withgcc11.2.120210728(RedHat11.2.1-1)

$ java -Xinternalversion–version

OpenJDK64-BitServerVM (11.0.13+8)forlinux-amd64 JRE (11.0.13+8),built on Nov8202100:00:00by "mockbuild"withgcc11.2.120210728(RedHat11.2.1-1)

高级选项

这些参数不是随意使用的,而是用于调整 Hotspot VM 的特定区域。这些参数可能会发生变化,并且不能保证得到所有 JVM 实现的支持。

这些参数以 -XX 开头。如需列出参数列表,使用如下命令:

  1. $ java -XX:+UnlockDiagnosticVMOptions-XX:+PrintFlagsFinal-version

例如,需要跟踪类的加载,那么使用下面的命令:

  1. $ java -XX:+TraceClassLoadingHello

在 Hello.java 中:

  1. publicclassHello{

  2. publicstaticvoidmain(Stringargs){

  3. System.out.println(“Inside Hello World!”);

  4. }

  5. }

publicclassHello{

publicstaticvoidmain(Stringargs){

System.out.println(“Inside Hello World!”);

}

}

另一个可能会面临的问题是 OOM( 内存超出 (Out Of Memory) )错误,它发生的时候可能没有太多的调试信息。为了解决这个问题,使用调试参数 -XX:+HeapDumpOnOutOfMemoryError ,它可以创建一个带有调试信息的 .hprof 文件。

  1. // TestClass.java

  2. importjava.util.ArrayList;

  3. importjava.util.List;

  4. publicclassTestClass{

  5. publicstaticvoidmain(Stringargs){

  6. Listlist=newArrayList;

  7. for(inti =0;i <1000;i++){

  8. list.add(newchar[1000000]);

  9. }

  10. }

  11. }

// TestClass.java

importjava.util.ArrayList;

importjava.util.List;

publicclassTestClass{

Listlist=newArrayList;

for(inti =0;i <1000;i++){

list.add(newchar[1000000]);

}

}

}

  1. $ JavacTestClass.java

  2. $ java -XX:+HeapDumpOnOutOfMemoryError-Xms10m-Xmx1gTestClass

  3. java.lang.OutOfMemoryError:java heap space

  4. Dumpingheap to java_pid444496.hprof …

  5. Heapdumpfilecreated [1018925828bytes in1.442secs]

  6. Exceptioninthread "main"java.lang.OutOfMemoryError:java heap space

  7. at TestClass.main(TestClass.Java:8)

$ JavacTestClass.java

$ java -XX:+HeapDumpOnOutOfMemoryError-Xms10m-Xmx1gTestClass

java.lang.OutOfMemoryError:java heap space

Dumpingheap to java_pid444496.hprof …

Heapdumpfilecreated [1018925828bytes in1.442secs]

Exceptioninthread "main"java.lang.OutOfMemoryError:java heap space

at TestClass.main(TestClass.Java:8)

有一些工具 🔗 opensource.com 可以查看这个 .hprof 文件以了解问题所在。

总结

通过了解和使用 JVM 以及 JVM 参数,开发人员和终端用户都可以诊断故障并提高 Java 应用程序的性能。下次使用 Java 时,请花点时间看看有哪些参数可以用吧!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值