团队从 Oracle JRE 1.8 切换到 OpenJDK。开始测试这个版本:
java-1.8.0-openjdk-1.8-Ø.372
一切正常,直到负载测试开始并转移到更高的暂存环境。团队开始出现以下错误:
无法使用-Xmx1024m启动应用程序:
Error occurred during initialization of VM
Could not reserve enough space for 1048576KB object heap
然后,将 JVM 内存参数更改为 -Xmx512m(或者杀死 Windows Server 上一些不需要的后台服务/任务),应用程序将成功启动,然后在负载测试中途开始抛出以下错误:
java.lang.OutOfMemoryError: Java heap space
有以下限制:必须使用 JRE 32 位版本 1.8.0_341 或更低版本,因为使用的 JDK 是基于 1.7 的。 32 位是由于使用了其他不适用于 64 位的组件。
我进行了广泛的研究,并发现了各种文章,包括这篇文章:
请注意,该应用程序已使用 Oracle 的 JRE 1.8 更新 341 运行多年,没有任何错误。
我有以下故障排除计划:
OpenJ9:https://developer.ibm.com/languages/java/semeru-runtimes/downloads/
热点:https://adoptium.net/temurin/releases/?version=8
尝试较低或较高版本的 OpenJDK,因为 Oracle JRE 版本和 OpenJDK 版本之间没有一对一的映射。
根据本文尝试其他GC算法:
https://developers.redhat.com/articles/2021/11/02/how-choose-best-java-garbage-collector
我需要您的帮助来找到其他故障排除选项,特别是如何使用 Java 工具开始分析和内存调试以查看出了什么问题。
接下来,我将提供有关 OpenJDK 的信息以及其他详细信息。
java -version -XshowSettings:properties
我得到以下信息:openjdk version "1.8.0_372"
OpenJDK Runtime Environment (build 1.8.0_372-b07)
OpenJDK Server VM (build 25.372-b07, mixed mode)
Property settings:
awt.toolkit = sun.awt.windows.WToolkit
file.encoding = Cp1252
file.encoding.pkg = sun.io
file.separator = \
java.awt.graphicsenv = sun.awt.Win32GraphicsEnvironment
java.awt.printerjob = sun.awt.windows.WPrinterJob
java.class.path = .
java.class.version = 52.0
java.endorsed.dirs = C:\Program Files (x86)\RedHat\java-1.8.0-openjdk-1.8.0.372-1\jre\lib\endorsed
java.ext.dirs = C:\Program Files (x86)\RedHat\java-1.8.0-openjdk-1.8.0.372-1\jre\lib\ext
C:\Windows\Sun\Java\lib\ext
java.home = C:\Program Files (x86)\RedHat\java-1.8.0-openjdk-1.8.0.372-1\jre
java.runtime.name = OpenJDK Runtime Environment
java.runtime.version = 1.8.0_372-b07
java.specification.maintenance.version = 4
java.specification.name = Java Platform API Specification
java.specification.vendor = Oracle Corporation
java.specification.version = 1.8
java.vendor = Red Hat, Inc.
java.vendor.url = https://developers.redhat.com/
java.vendor.url.bug = https://bugzilla.redhat.com/enter_bug.cgi
java.version = 1.8.0_372
java.vm.info = mixed mode
java.vm.name = OpenJDK Server VM
java.vm.specification.name = Java Virtual Machine Specification
java.vm.specification.vendor = Oracle Corporation
java.vm.specification.version = 1.8
java.vm.vendor = Red Hat, Inc.
java.vm.version = 25.372-b07
line.separator = \r \n
os.arch = x86
os.name = Windows Server 2019
os.version = 10.0
path.separator = ;
sun.arch.data.model = 32
sun.boot.class.path = C:\Program Files (x86)\RedHat\java-1.8.0-openjdk-1.8.0.372-1\jre\lib\resources.jar
C:\Program Files (x86)\RedHat\java-1.8.0-openjdk-1.8.0.372-1\jre\lib\rt.jar
C:\Program Files (x86)\RedHat\java-1.8.0-openjdk-1.8.0.372-1\jre\lib\sunrsasign.jar
C:\Program Files (x86)\RedHat\java-1.8.0-openjdk-1.8.0.372-1\jre\lib\jsse.jar
C:\Program Files (x86)\RedHat\java-1.8.0-openjdk-1.8.0.372-1\jre\lib\jce.jar
C:\Program Files (x86)\RedHat\java-1.8.0-openjdk-1.8.0.372-1\jre\lib\charsets.jar
C:\Program Files (x86)\RedHat\java-1.8.0-openjdk-1.8.0.372-1\jre\lib\jfr.jar
C:\Program Files (x86)\RedHat\java-1.8.0-openjdk-1.8.0.372-1\jre\classes
sun.boot.library.path = C:\Program Files (x86)\RedHat\java-1.8.0-openjdk-1.8.0.372-1\jre\bin
sun.cpu.endian = little
sun.cpu.isalist = pentium_pro+mmx pentium_pro pentium+mmx pentium i486 i386 i86
sun.desktop = windows
sun.io.unicode.encoding = UnicodeLittle
sun.java.launcher = SUN_STANDARD
sun.jnu.encoding = Cp1252
sun.management.compiler = HotSpot Tiered Compilers
sun.os.patch.level =
sun.stderr.encoding = cp437
sun.stdout.encoding = cp437
user.country = US
user.dir = C:\Program Files (x86)\RedHat\java-1.8.0-openjdk-1.8.0.372-1\bin
user.language = en
user.script =
user.timezone =
user.variant =
这是否意味着我正在使用 HotSpot OpenJDK?
Processor: Intel(R) Xeon(R) Platinum CPU @ 2.20GHz 2.19 GHz (16 processors)
Installed memory (RAM): 64.0 GB
System type: 64-bit Operating System, x64-based processor
Pen and Touch: Pen and Touch Support with 10 Touch Points
我安装了 VisualVM 并观看了一些教程。我想我有一个计划。我将获取 JVM 参数的转储,使用分析/采样/快照/堆转储,然后比较 OpenJDK 和 Oracle JDK 之间的差异。当抛出 OutOfMemeory 异常时,我还将使用选项来创建堆转储。
知道如何有效地使用 VisualVM 来找到此问题的解决方案吗?