同样的建议也适用于 GC 策略的选择。每个策略针对不同的用例。我们需要衡量和比较,以选择最佳策略。
通过正确的设置,OpenJ9 可以提供稳定的性能并节省资源。
penJ9 是一个高性能、可扩展且灵活的Java 虚拟机。我们可以在许多 Java 应用程序中使用它来替代 HotSpot。IBM 最初将其作为其商业 JDK 的一部分进行开发。现在,该 JVM 已获得 Eclipse 基金会的支持。
我们使用 OpenJ9 来减少内存占用和启动时间,尤其是在云和容器环境中。它支持 Java SE 规范,并且与 OpenJDK 完美兼容。本文将探讨如何安装 OpenJ9 JVM 并回顾其主要功能。
安装
我们可以通过下载包含 OpenJ9 的预构建 OpenJDK 二进制文件来安装它。许多发行版(例如 Eclipse Temurin)都提供了基于 OpenJ9 的版本。 官方发行列表位于 Eclipse OpenJ9 网站。
下载档案后,我们提取文件并设置JAVA_HOME环境 变量。
Windows
首先,我们将 ZIP 压缩包解压到指定位置,例如path-to-jdk\jdk-openj9。然后,设置JAVA_HOME环境变量并修改PATH环境变量:
$ setx JAVA_HOME "path-to-jdk\jdk-openj9" |
最后我们验证安装:
$ java -version |
Linux
首先,让我们提取档案:
$ tar -xzf OpenJ9-JDK.tar.gz -C /opt |
然后我们设置JAVA_HOME并更新PATH:
$ export JAVA_HOME=/opt/jdk-openj9 |
我们可以将这些行添加到.bashrc或.zshrc中,以使它们永久生效。最后,我们检查安装:
$ java -version
现在我们准备使用 OpenJ9 来运行和开发 Java 应用程序。
垃圾收集策略
OpenJ9 提供了多种垃圾收集策略。每种策略都针对不同的工作负载进行了优化。我们可以选择最符合自身性能目标的策略。
在 HotSpot JVM 中,我们通过选择GC 实现并调整许多参数来配置垃圾回收。在 OpenJ9 中,我们使用 GC 策略。每种策略都是针对特定用例设计的,我们在启动时使用虚拟机选项选择一种策略:
-Xgcpolicy:<name> |
让我们看看 OpenJ9 中可用的 GC 策略。
1. 分代并发 GC 策略
这是默认策略,我们将在大多数应用程序中使用它。使用此 GC 策略,我们将堆划分为两个区域:新生代 (nursery)和老生代 (tenure)。此策略管理两个代组:新生代 (new)和老生代 (older)。
它使用并发标记-清除执行全局 GC,并可选地执行压缩。部分 GC 是一种 Stop-the-world 清除或并发清除。
我们使用以下标志启用它:
-Xgcpolicy:gencon |
2. 平衡策略
当我们遇到gencon暂停时间过长的问题时,我们会将此策略用于大型堆和多线程。此策略将堆划分为大小相等的区域,并获得多代支持。
全局 GC 使用增量并发标记。部分 GC 使用 Stop-the-world 以及可选的标记、清除或压缩。
我们可以使用标志添加此策略:
-Xgcpolicy:balanced |
3. 优化暂停时间策略
我们选择此策略是为了最大限度地减少暂停时间。例如,当堆大小较大并且会影响 GC 暂停时长时,此策略可能很有用。此策略使用单个平坦的堆区域。这里我们只有一代。
GC 是并发标记-清除,带有可选的压缩。
要开始使用此策略,我们必须添加以下标志:
-Xgcpolicy:optavgpause |
4. 优化吞吐量策略
当我们希望在短期应用程序中实现最大吞吐量时,我们会选择此策略。此处我们有一个平坦的堆区域。此策略支持单代。
GC 是一种具有可选压缩功能的 Stop-the-World 标记-清除操作。
我们可以使用以下标志启用此策略:
-Xgcpolicy:optthruput |
5. Metronome 节拍器策略
我们将此策略用于实时和软实时应用。它将堆划分为按大小分类的区域。这样我们就可以获得一代的支持。
节拍器 GC 以短暂可中断的突发方式运行,以避免长时间的停止世界暂停。
要使用节拍器策略,我们可以打开标志:
-Xgcpolicy:metronome |
6. nogc策略
我们使用此策略进行测试或内存不回收的特殊用例。这里我们有一个扁平堆。不执行任何 GC。
我们可以使用以下标志启用它:
-Xgcpolicy:nogc |
类数据共享和 AOT 编译
OpenJ9开箱即用地支持类数据共享和提前编译。我们可以利用这些特性来缩短启动时间并减少内存占用。
1. 类数据共享
类数据共享允许我们将类元数据缓存在共享内存缓存中。我们只需创建一次共享类缓存,即可在 JVM 运行期间重复使用它。这可以加快类加载速度并减少内存占用,尤其是在容器和微服务环境中。
为了启用 CDS,我们使用以下标志启动 JVM:
-Xshareclasses
我们还可以命名缓存并控制其大小:
-Xshareclasses:name=myCache,cacheDir=/path/to/cache,cacheSize=100M
要查看缓存统计信息,我们使用:
-Xshareclasses:cacheStats
2. 提前编译
OpenJ9 中的预编译功能会在运行时之前将 Java 字节码编译为原生代码。这减少了 JIT 的预热时间,并提高了启动性能。
与需要 GraalVM 进行 AOT 编译的 HotSpot 不同,OpenJ9 内置了对 AOT 的支持。 虚拟机会自动选择哪些方法应该基于 AOT 编译,但我们可以使用以下标志禁用此功能:
-Xnoaot
诊断数据和工具
OpenJ9 和 HotSpot 一样支持 JMX,我们可以将现有的监控工具连接到它。
此外,OpenJ9 还提供了其他工具,可用于排查性能问题、崩溃或内存问题。我们可以使用转储代理来生成堆转储、系统转储和常规 JVM 信息转储。