Java 开发人员 JVM 参数指南

通过理解和使用 JVM 和 JVM 参数,开发人员和最终用户都可以诊断故障并提高 Java 应用程序的性能。
2 位读者喜欢这篇文章。
woman on laptop sitting at the window

CC BY 3.0 US Mapbox Uncharted ERG

当你编写源代码时,你是在为人类编写可读的代码。计算机无法执行源代码,除非代码被编译成机器语言,这是一个通用术语,指特定机器所需的任何数量的语言。通常,如果你在 Linux 上编译代码,它就在 Linux 上运行,如果你在 Windows 上编译代码,它就在 Windows 上运行,等等。然而,Java 是不同的。它不针对实际的机器。它针对的是 Java 虚拟机 (JVM),因此它可以运行在任何机器上。

Java 源代码被编译成字节码,由安装在计算机上的 JVM 运行。JVM 是一个执行引擎,但通常你不会直接与之交互。它静默运行,处理 Java 字节码。大多数人不需要考虑甚至了解 JVM,但了解 JVM 的工作原理对于调试和优化 Java 代码可能很有用。例如

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

  • 如果在你编写的应用程序中出现问题,开发人员和最终用户都可以选择调试问题。

  • 如果你想了解用于开发或运行 Java 应用程序的 Java 开发工具包 (JDK) 的详细信息,你可以通过查询 JVM 获取这些详细信息。

本文介绍了一些基本的 JVM 参数,以帮助应对这些情况……

Jvm parameters

(Jayashree Huttanagoudar CC BY-SA 4.0)

JVM、JDK 和 JRE 之间有什么区别?

Java 有很多 J 开头的首字母缩略词,包括 JVM、JDK 和 JRE。

  • Java 开发工具包 (JDK) 供需要在代码中使用开发库的程序员访问。

  • Java 运行时环境 (JRE) 供想要运行 Java 应用程序的人员使用。

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

JDK 包含 JRE 和 JVM,但一些 Java 发行版提供了包含 JRE(包括 JVM)的备用下载。

JDK

(Jayashree Huttanagoudar CC BY-SA 4.0)

Java 是开源的,因此不同的公司构建和分发 JDK。你可以在你的系统上安装多个 JDK,这在你处理或使用不同的 Java 项目时可能很有用,其中一些项目可能使用旧的 JDK。

要列出你的 Linux 系统上的 JDK,你可以使用 alternatives 命令

$ alternatives --config java
There are 2 programs that provide java.
Selection Command
-----------------------------------------------
*+ 1 java-11-openjdk.x86_64 (/usr/lib/jvm/java-11-openjdk-11.0.13.0.8-2.fc35.x86_64/bin/java)
2 java-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)

Enter to keep the current selection[+], or type selection number:

要在可用的 JDK 之间切换,再次运行该命令

$ sudo alternatives --config java

另一种选择是使用 SDKMan,它可以帮助你下载、更新和管理系统上的 JDK。

什么是 JVM 调优?

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

一般来说,在调优之前考虑以下几点很重要

  • 成本:有时,改进运行代码的硬件可以提高应用程序的性能。这可能看起来像是一种“作弊”,但请考虑你愿意花多少时间来调优 JVM 参数。有时,应用程序需要更多内存才能达到预期的性能,而再多的软件技巧也无法改变这一点。

  • 预期结果:从长远来看,稳定性比性能更重要。如果你的调优影响了稳定性,那么最好明智地选择你的调优参数。

  • 底层问题:有时,问题可能是主机操作系统存在底层问题。在调优 JVM 之前,请确保 JVM 的平台运行正常。

  • 内存泄漏:如果你发现自己正在使用垃圾回收 (GC) 调优参数,则很可能存在需要在应用程序代码中修复的内存泄漏。

JVM 参数的类型

JVM 参数分为三个类别:标准选项、非标准选项和高级选项。

标准选项

所有 JVM 实现都支持标准选项。在终端中运行“java”命令以查看标准选项列表。

$ java
Usage: java [options] <mainclass> [args...]
       	(to execute a class)
   or  java [options] -jar <jarfile> [args...]
       	(to execute a jar file)

 where options include:

	-cp <class search path of directories and zip/jar files>
	-classpath <class search path of directories and zip/jar files>
	--class-path <class search path of directories and zip/jar files>
         	A : separated list of directories, JAR archives,
          	and ZIP archives to search for class files.
	--enable-preview
         	allow classes to depend on preview features of this release

To specify an argument for a long option, you can use --<name>=<value> or
--<name> <value>.

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

$ java --dry-run <classfile>

非标准选项

非标准选项以 -X 开头。这些选项用于通用目的,并且特定于 JVM 的特定实现。要列出这些选项
 

$ java -X
-Xbatch disable background compilation
-Xbootclasspath/a:<directories and zip/jar files separated by :>
append to end of bootstrap class path
-Xinternalversion
displays more detailed JVM version information than the
-version option
-Xloggc:<file> log GC status to a file with time stamps
[...]

这些额外的选项可能会在没有通知的情况下更改,并且并非所有 JVM 实现都支持这些选项。

Microsoft 构建的 JVM 可能与 Red Hat 构建的 JVM 有不同的选项,依此类推。

要获取详细的 JVM 版本信息,请使用以下选项
 

$ java -Xinternalversion --version
OpenJDK 64-Bit Server VM (11.0.13+8) for linux-amd64 JRE (11.0.13+8), built on Nov 8 2021 00:00:00 by "mockbuild" with gcc 11.2.1 20210728 (Red Hat 11.2.1-1)

要获取属性设置,请使用

$ java -XshowSettings:properties --version

高级选项

这些选项不适合随意使用,而是用于调优 Hotspot VM 的特定区域。这些选项可能会更改,并且不保证所有 JVM 实现都支持这些选项。

这些选项以 -XX 开头。要列出这些选项,请使用以下命令

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

例如,要跟踪类加载,请使用以下命令

$ java -XX:+TraceClassLoading Hello

Hello.java 具有

$ cat Hello. java
public class Hello {
  public static void main(String[] args) {
    System.out.println("Inside Hello World!");
  }
}
 

你可能面临的另一个常见问题是 OOM(内存溢出)错误,这可能在没有太多调试信息的情况下发生。要解决此类问题,你可以使用调试选项 -XX:+HeapDumpOnOutOfMemoryError,它会创建一个包含调试信息的 .hprof 文件。
 

$ cat TestClass. java
import java.util.ArrayList;
import java.util.List;

public class TestClass {
  public static void main(String[] args) {
    List<Object> list = new ArrayList<Object>();
    for (int i = 0; i < 1000; i++) {
      list.add(new char[1000000]);
    }
  }
}
$ Javac TestClass.java
$ java -XX:+HeapDumpOnOutOfMemoryError -Xms10m -Xmx1g TestClass
java.lang.OutOfMemoryError: java heap space
Dumping heap to java_pid444496.hprof ...
Heap dump file created [1018925828 bytes in 1.442 secs]
Exception in thread "main" java.lang.OutOfMemoryError: java heap space
at TestClass.main(TestClass.Java:8)

有一些工具 可以查看此 .hprof 文件,以了解哪里出了问题。

结论

通过理解和使用 JVM 和 JVM 参数,开发人员和最终用户都可以诊断故障并提高 Java 应用程序的性能。下次你使用 Java 时,花点时间看看可用的选项。

标签
User profile image.
Jayashree Huttanagoudar 是 Red Hat India Pvt ltd 的高级软件工程师。她在 Middleware OpenJDK 团队工作。她总是对学习新事物充满好奇,这为她的工作增添了色彩。

评论已关闭。

© 2025 open-source.net.cn. All rights reserved.