适用于 Minecraft 的 JVM 选择和调优参数个人经验总结(停更)
琉璃倒映姬沁雪
编辑于 2026年01月05日 17:59

文 | Beiatorisu

校 | Beiatorisu

一、前言

起因是我个人使用 Sodium 开发者推荐的 Temurin JDK 和官方启动器以及 PCL 启动器自带的参数运行 ATM9 和 ATMS 这种大型整合包后期感受到了严重的卡顿,这种卡顿是各方面的,包括但不限于抽象的不稳定的帧生成时间曲线、极高的 MSPT 导致交互迟缓、内存占用无上限飙升导致系统频繁进行虚拟内存 swap 造成所有程序的冻结,极其缓慢的区块加载和区块行为频繁导致游戏甚至系统冻结。

总之这种游戏体验实在是太牙白了,不能说是糟糕透顶,至少也是毫无体验可言,让我回想起曾经用 XP 系统和奔腾双核玩 1.13 海洋更新时的上古记忆,虽然现在也只不过是从双核变成了四核……

在很长的时间里,我也认为不同的 JVM 和启动参数和并没有什么差异这一观点的准确性,但在折腾了很长时间后,我可以明确的说,在 Modded Minecraft 里(而在原版则确实较小)不同 JVM 差距还是比较明显的,而不同 JVM 参数依靠不同的环境和需求则有更大的影响,尤其是对于内存敏感的情景。折腾 JVM 确实可以得到一定的性能提升。

但无论是换上了合适的 JVM 还是参数,最终也只能优化一定的体验,很难魔法一般让老平台完全起死回生。Java 和 JVM 参数优化应该是 MC 优化的末级,只有折腾完优化模组之后才应该努力于此,榨干设备的最后一丝潜力和性能。

1.5: To-Do List

-> 把各项来源参考资料的数据汇总到一起制作表格

-> Java 8/11 各发行版的参数和 ConcMarkSweep GC

-> Zing Ready Now ()

-> Dragonwell JWarmup

-> JDK 23+ 的 AOT 应用启动和带 AOT 的分层编译

-> Tencent Kona 8 的各种优化 G1GC

-> 测评 JetBrains Runtime 的性能

二、Java 选择

介绍了一圈,顺便说说优势,大部分来自于空桑大佬的测评帖,推荐也看看,数据最全面的评测了):

考虑到现在很多 Java 发行版都不是完全基于 HotSpot,在这里简单介绍一下 HotSpot,作为 Java HotSpot Performance Engine 发布,是一个用于桌面和服务器计算机的 Java 虚拟机,由

Sun Microsystems 开发,现在由 Oracle 公司维护和分发。它通过实时编译和自适应优化等方法提高了性能。后文中如果存在不完全基于 HotSpot 的 JVM 实现方式,也会标注一下。

Zing VM / Azul Platform Prime

一个真正卓越并饱受行业好评的 Java 运行平台,可以将硬件基础设施的经济成本降低一半。Zing VM 通过超优化的运行时间增强 Java 生态系统的性能和可扩展性,最大限度地提高了性能,同时显著降低基础设施的建设成本。拥有别具一格的 C4GC,为最早做到极低暂停时长的 GC。使用区别于一般 JIT 的 Facon JIT,还有 ReadyNow预热。Zing VM 的实现方式也和通常 OpenJDK 发行版的 HotSpot VM 不同,所以在 MC 这边有很多不兼容性的报告。并且 Zing VM 只支持 Linux 系统,由于某些实现方式,几乎不可能推出 Windows 版本,由于笔者没有 Linux 机器,而且 Zing VM 的参数和所有 HotSpot 都不经相同,所以本贴中不会赘述,只在此简单介绍一下。

Oracle GraalVM / GraalVM Enterprise Edition (最推荐)

Java 本家 Oracle 公司的新技术,包含了大量独特的特性,更快速、更智能、更精简。作为备受好评的高性能 JDK,可提高基于 Java 和 JVM 的应用的性能并简化 Java 云原生服务的构建和运行(也就是将 Java 程序编译为 Native Image,使用和 C++ 程序相同的字节码在本地运行,真正做到了脱离 Java VM,但 MC 其实更适合 JIT)。它提供优化的编译器(Graal JIT),可以更快地生成代码并降低计算资源消耗,实现 Java 程序快速启动。GraalVM 包含 Java SE。通常情况下个人使用无需付费。GraalVM 的 JVM 运行方式其实算是独立于 HotSpot 的另一种 JVM 实现,但因为也大量复用了 HotSpot 代码和架构,所以相较于 Zing VM,几乎没有不兼容的插件和模组。

Alibaba Dragonwell Extended Edition / Standard Edition

在国内从 MCBBS 时代一路火下来的 Java 发行版,实测效果相当不错,即便是补丁缺少的 SE 也远超被政治正确推荐荼毒的 Temurin(见 5),在原版的运行中通常提供更高的帧数,在复杂的模组环境中也能很好的节省内存,不过可惜的是作为好评最多功能最强最为丰富之一的 Java 8 发行版,Windows 却是个残血版,这点真的颇为可惜,希望阿里团队腾出手后能考虑把独家特性带到更多平台。

官方介绍 Dragonwell 是一款免费的, 生产就绪型 Open JDK 发行版,提供长期支持,包括性能增强和安全修复。阿里巴巴拥有最丰富的 Java 应用场景,覆盖电商,金融,物流等众多领域,世界上最大的 Java 用户之一。Alibaba Dragonwell 作为 Java 应用的基石,支撑了阿里经济体内所有的 Java 业务,比如著名的双十一后端数据处理,这种高压程度毋庸置疑。

Zulu / Azul Platform Core (OpenJDK最稳定的)

相较于 Zing VM / Platform Prime Zulu 不再使用 Azul 独有的 G4GC,而专注于增强 HotSpot 自身,但 GC 暂停时间和消耗资源和比其他 OpenJDK 发行版要低,也有更少的 mixed GC,能极大提高应用程序的流畅性。虽然技术不太同,但运行效果与 OpenJDK 发行版相差较少,没有迁移成本或兼容性问题。不过生成区块测试中名列 HotSpot 倒数,可能是为了总体稳定性牺牲了峰值性能,Java 8 除外。

自称为世界上技术支持最好的公共 OpenJDK 版本,Azul 的资历和技术力也确实能支撑这一结论。号称能比 Oracle 少 70% 的基础设施建设成本(但更多是采购费用),Azul Platform Core 专为企业而设计,具有运行当今基于 Java 的业务关键型服务所需的认证版本、严格的安全性和成本效率。

IBM Semeru Runtime / OpenJDK with Eclipse OpenJ9

说人话就是以低内存和高稳定性助长的 JDK,拥有和其他所有 JDK 不同的 GC 策略,所以看到很多攻略里给 J9 上 G1GC 我就有些无语。在 Java 8 时代和 Zing, Dragonwell 都是早期做到类 AOT 高速预热的发行版,但因为本身性能不出色所以名声发源于 FTB 1.12.2 社区中的低配玩家,在那个时期的低配机上虚拟内存 swap 交换的开销完全压倒了 MC 本身的执行,即虽 MC 很吃 CPU 但其实内存开销也很多,并常常被忽视,在内存容量低的电脑上过多模组运行时会产生很大的虚拟内存开销,系统从磁盘和内存间来回交换虚拟内存(swap)会导致极其严重的 CPU 开销,任务管理器里还一般看不到,如果内存提交能下去反而会有更多资源给 MC 吃,这个时候该 JDK 本身执行效率极低反而就很难凸显了。其实场景上 MC 并不是很适合 J9。在 JDK 21 上吞吐量已超过 OpenLogic OpenJDK 这种 HotSpot 吊车尾,但兼容性更难绷了。

为使用 OpenJDK 中的类库以及 Eclipse OpenJ9 Java 虚拟机,使开发人员能够构建和部署 Java 应用程序,这些应用程序将快速启动,提供出色的性能,同时使用更少的内存。

RedHat Builds of OpenJDK

正统 Shenandoah GC,该 GC 是红帽研发的,因此红帽的 JDK 应该也是适配最好的,而且是唯一一个在 Java 8 上提供 Shenandoah GC 的发行版,如果需要玩 1.12.2 以下的 Modded MC 同时又因为兼容性或者别的原因用不上 Cleanroom 和 LWJGL3Ify,那么唯一应该选择的就是红帽发行的 OpenJDK 8,除了 GC 之外综合性能与稳定性也十分出色。理论上来说,红帽 JDK 仅供 RHEL 使用,但 Windows 版的表现相当相当出色。

官方介绍 Oracle JDK 已不再免费提供生产工作负载和补丁,红帽 ® 版 OpenJDK 是 Java 平台标准版(Java SE)的一个免费开源实现。该替代方案可以让您的企业在未来数年内几乎无需进行任何迁移工作,便能稳定和标准化自己的 Java 环境。

Tencent Kona

腾讯发行的 JDK,专注增强 Java 8 和 Java 11,比 Dragonwell 的配方少一些,但好于 Windows 版没有明显残血,Java 17 和 21 有更好的选择,只有 8 和 11 可以考虑该发行版。

官方介绍 Tencent Kona 是一个基于 OpenJDK 定制的,生产环境可用,高性能,安全稳定,兼容多种运行平台的 OpenJDK 开源发行版本。提供企业级 JDK 服务,由腾讯专业技术团队提供技术维护、性能优化及安全保障等服务,为客户提供最优的 Java 云生产环境及解决方案。

Amazon Corretto

为了应对 Oracle JDK 许可证的变化,亚马逊也维护了一份 OpenJDK 发行版,似乎是最早 Frok Java 的云厂商。Forge 官方推荐的就是这个发行版,实际运行的效果也还可以,都留空全默认参数下高压环境综合评比,TPS/mspt 表现还算稳,内存占用是 OpenJDK 的一流行列,不过单项测试里很多时候表现平平无奇。

官方介绍 Amazon Corretto 是开放 Java 开发工具包 (OpenJDK) 的免费、多平台、生产就绪型发行版。Corretto 提供长期支持,其中包括性能增强和安全修复。亚马逊在内部的数千种生产服务上运行 Corretto,并且 Corretto 已被证明能够兼容 Java SE 标准。借助 Corretto,您可以在常用操作系统(包括 Linux、Windows 和 macOS)上开发和运行 Java 应用程序。

BellSoft Liberica JDK

另一个类似 Azul 公司,他们做的 JDK 包含了很多额外的补丁和性能增强,在 Java 开发者和使用上似乎有很多拥簇,但普通版(因为还有个秘方加料版很 OP)在 MC 的表现上并不算好,不过该发行版是少数在 Java 17/Java 21 上提供 x86 32位版本的厂商,而且经过了比较多的测试, 虽然很多 JVM 参数用不了,但兼容性还是可以的,Windows 7 上也有吧友运行成功。其实他们发行版的核心产品是 Liberica JDK Performance Edition,该发行版的子版本把 Shenandoah、Generational ZGC、Virtual Thread、Project Lilliput 等一众 Java LTS 17/21/25 特性移植回了 Java 8 和 Java 11,高版本 Java 的 JVM 参数能无痛直接用,但只支持 Linux 系统就。。。又有些操蛋。

Eclipse Adoptium Temurin

这个发行版的前身是大名鼎鼎的 AdoptOpenJDK,没错就是 2019 年大火的很多 Java 换版本优化 MC 教程里的厂商,在 Oracle Java SE 转成商业付费后很长一段时间依靠知名度垄断了 OpenJDK 下载榜单,即便是商标变成 Adoptium 后也拉了一大堆 Java 领域的大厂一起做,大有一幅成为 OpenJDK 的最大公约数和标准的势头。胜在兼容性,实测效果已经不如更具独门秘籍的 JDK 了,虽然自称高性能发行版但其实性能本身来源于高版本 Java 自身的特性,比起拥有独门秘方的其他厂商来说,老东西该爆金币了。

官方介绍基于 OpenJDK:Eclipse Temurin 提供高性能、跨平台的开源 Java™ 运行时二进制文件,适用于企业环境,已通过 Java SE TCK 认证并经 AQAvit 验证,适用于 Java 生态系统中的广泛使用。Eclipse Temurin 是 Adoptium OpenJDK 发行版的名称。

Oracle JDK / Oracle OpenJDK

曾经占据大部分市场份额的 JDK,但后来因为协议变更而臭名昭著,实际上低版本 8/11 被各路带有独家秘方的发行版打成狗,但在结合多方数据 17 和 21 上的运行效果并不算差,服务端表现虽然也不太好但客户端上偶尔能超神一下,图稳定或者怀旧或许可以用,但注意不包含 Shenandoah GC。

Oracle Java 是广受欢迎的编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今,Java 仍是企业和开发人员的首选开发平台,全球有数百万开发人员运行超过 60 亿台 Java 虚拟机。

Microsoft Builds of OpenJDK

官方启动器钦定版本,微软的 OpenJDK 发行版,在细枝末节上也有一些奇怪的改进。实际效果上服务端只能说中规中矩,但也比 Temurin 这种应该爆金币的老大爷要好,不过到客户端表现 (更侧重 FPS) 其实比 Zulu 和 Dragonwell 要好点,Minecraft 应该就是用这个发行版开发的,如果不想折腾就用官方启动器下载的这个吧。

官方介绍 Microsoft Build of OpenJDK 是 OpenJDK 的一种免费分发版,它是开放源代码,任何人都可将其免费部署到任意位置。

Jebrains Runtime

黑马之一。图形性能极其优秀的 JDK (但依旧需要更多测试),唯一一个号称专业增强图形性能的 JDK 发行版,还包括大量其他的增强补丁和性能优化,可以在不重启 MC 时配置完模组功能,也就是类交换,并且在 Java 21 平台 (Cleanroom、LWJGL3ify、1.20.1 Modded 兼容性良好) 上 backport 了大量 JDK LTS 25 的功能,包括 Project Leyden、Project Lilliput、AOT、Generational Shenandoah 等大量特性,Sodium、Iris、Embeddium、Oculus 等一众熟悉的 Mod 也都是在这个 JDK 环境下开发和调试的。

官方介绍 JetBrains Runtime 是一个运行时环境,用于在 Windows、Mac OS X 和 Linux 上运行 OpenJDK 项目,它支持增强类重定义,并进行了一些功能增强,包括抗锯齿、更好的字体渲染、 HiDPI 支持、连字、一些官方版本中未提供的针对产品崩溃的修复程序以及其他小的增强功能。不过JetBrains Runtime不是OpenJDK的认证版本,稳定性上可能存在风险。

SAPMachine Binary

黑马之一。四大 ERP 软件开发商之一推出的发行版,类似 Jebrains Runtime 同样在 Java 21 上 backport 了大量 LTS 25 的内容,该版本拥有很强的稳定性沉淀,在高压测试中是受高压影响最小的发行版之一,几乎接近 Zing 的稳定性。

官方介绍,此项目包含 OpenJDK 项目的下游版本。它用于为希望使用 OpenJDK 运行其应用程序的 SAP 客户和合作伙伴构建和维护 SAP 支持的 OpenJDK 版本。

三、Java 启动参数(JVM Flags)

OpenJDK 17/OracleJDK 17 通用基础参数(*需要加GC)

-XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysActAsServerClassMachine -XX:+AlwaysPreTouch -XX:+DisableExplicitGC -XX:NmethodSweepActivity=1 -XX:ReservedCodeCacheSize=400M -XX:NonNMethodCodeHeapSize=12M -XX:ProfiledCodeHeapSize=194M -XX:NonProfiledCodeHeapSize=194M -XX:-DontCompileHugeMethods -XX:MaxNodeLimit=240000 -XX:NodeLimitFudgeFactor=8000 -XX:+UseVectorCmov -XX:+PerfDisableSharedMem -XX:+UseFastUnorderedTimeStamps -XX:+UseCriticalJavaThreadPriority -XX:+UseStringDeduplication -XX:+UseAES -XX:+UseAESIntrinsics -XX:+UseFMA -XX:+UseCompressedOops -XX:+UseFPUForSpilling -XX:+UseNewLongLShift -XX:+UseVectorCmov -XX:+UseXMMForArrayCopy -XX:+UseXmmI2D -XX:+UseXmmI2F -XX:+UseXmmLoadAndClearUpper -XX:+UseXmmRegToRegMoveAll -XX:+EnableVectorSupport -XX:+UseCharacterCompareIntrinsics -XX:+UseCopySignIntrinsic -XX:+UseVectorStubs -XX:ThreadPriorityPolicy=1 -XX:+OptoBundling -XX:+AlwaysCompileLoopMethods -XX:+EnableVectorAggressiveReboxing -XX:+OptoScheduling -XX:+TrustFinalNonStaticFields -XX:+UseBiasedLocking -Dlog4j2.formatMsgNoLookups=true -Djdk.lang.Process.allowAmbiguousCommands=true

OpenJDK 21/OracleJDK 21 通用基础参数(*需要加GC)

-XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysActAsServerClassMachine -XX:+AlwaysPreTouch -XX:+DisableExplicitGC -XX:-DontCompileHugeMethods -XX:+PerfDisableSharedMem -XX:+UseCriticalJavaThreadPriority -XX:+UseStringDeduplication -XX:ThreadPriorityPolicy=1 -XX:NmethodSweepActivity=1 -XX:ReservedCodeCacheSize=400M -XX:NonNMethodCodeHeapSize=12M -XX:ProfiledCodeHeapSize=194M -XX:NonProfiledCodeHeapSize=194M -XX:MaxInlineSize=256 -XX:InlineSmallCode=4000 -XX:MaxNodeLimit=240000 -XX:NodeLimitFudgeFactor=8000 -XX:+UseNewLongLShift -XX:+UseVectorCmov -XX:+UseXmmI2D -XX:+UseXmmI2F -XX:+AlignVector -XX:+OptimizeFill -XX:+EnableVectorSupport -XX:+UseCharacterCompareIntrinsics -XX:+UseCopySignIntrinsic -XX:+UseVectorStubs -XX:+ExplicitGCInvokesConcurrent -XX:+OptoBundling -XX:+AlwaysCompileLoopMethods -XX:+EnableVectorAggressiveReboxing -XX:+OptoScheduling -XX:+TrustFinalNonStaticFields -Dlog4j2.formatMsgNoLookups=true -Djdk.lang.Process.allowAmbiguousCommands=true

GraalVM 17 EE 通用基础参数(*需要加GC)

-XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysActAsServerClassMachine -XX:+AlwaysPreTouch -XX:+DisableExplicitGC -XX:NmethodSweepActivity=1 -XX:ReservedCodeCacheSize=400M -XX:NonNMethodCodeHeapSize=12M -XX:ProfiledCodeHeapSize=194M -XX:NonProfiledCodeHeapSize=194M -XX:MaxInlineSize=256 -XX:InlineSmallCode=4000 -XX:ThreadPriorityPolicy=1 -XX:+EagerJVMCI -XX:+UseJVMCICompiler -XX:-DontCompileHugeMethods -XX:+TrustFinalNonStaticFields -XX:+AllowParallelDefineClass -XX:+UseCriticalJavaThreadPriority -XX:+UseStringDeduplication -XX:+UseNewLongLShift -XX:+UseVectorCmov -XX:+UseVectorStubs -XX:+AlignVector -XX:+UseXmmI2D -XX:+UseXmmI2F -XX:+OptimizeFill -XX:+EnableVectorSupport -XX:+ExplicitGCInvokesConcurrent -XX:+OptoBundling -XX:+OptoScheduling -XX:+AlwaysCompileLoopMethods -XX:+EnableVectorAggressiveReboxing -XX:+UseBiasedLocking -Dlog4j2.formatMsgNoLookups=true -Djdk.lang.Process.allowAmbiguousCommands=true -Dgraal.CompilerConfiguration=enterprise -Dgraal.SpectrePHTBarriers=None -Dgraal.TuneInlinerExploration=1 -Dgraal.VectorizeSIMD=true -Dgraal.OptWriteMotion=true -Dgraal.WriteableCodeCache=true -Dgraal.BaseTargetSpending=160

GraalVM 21 EE 通用基础参数(*需要加GC)(已修复感谢私信)

之前贴重了先用17的凑合吧,之后更新新的,Java21只是很多东西变成了更优的默认参数,移除了一些参数,本质上区别比较少 ---已修复---

-XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysActAsServerClassMachine -XX:+AlwaysPreTouch -XX:+DisableExplicitGC -XX:ReservedCodeCacheSize=400M -XX:NonNMethodCodeHeapSize=12M -XX:ProfiledCodeHeapSize=194M -XX:NonProfiledCodeHeapSize=194M -XX:MaxInlineSize=256 -XX:InlineSmallCode=4000 -XX:+EagerJVMCI -XX:-DontCompileHugeMethods -XX:+AllowParallelDefineClass -XX:+UseStringDeduplication -XX:+UseNewLongLShift -XX:+UseVectorCmov -XX:+UseVectorStubs -XX:+AlignVector -XX:+UseXmmI2D -XX:+UseXmmI2F -XX:+OptimizeFill -XX:+ExplicitGCInvokesConcurrent -XX:+AlwaysCompileLoopMethods -XX:+OptoBundling -XX:+OptoScheduling -XX:+TrustFinalNonStaticFields -Dlog4j2.formatMsgNoLookups=true -Djdk.lang.Process.allowAmbiguousCommands=true -Dgraal.CompilerConfiguration=enterprise -Dgraal.SpectrePHTBarriers=None -Dgraal.TuneInlinerExploration=1 -Dgraal.VectorizeSIMD=true -Dgraal.OptWriteMotion=true -Dgraal.WriteableCodeCache=true -Dgraal.BaseTargetSpending=160

中文编码(防止乱码)

-Dfile.encoding=UTF-8 -Dstderr.encoding=UTF-8 -Dstdout.encoding=UTF-8

如果游戏或 log 依旧乱码,则在末尾加上

chcp 65001 # for Windows

G1GC (经典客户端 GC)

-XX:+UseG1GC -XX:MaxGCPauseMillis=37 -XX:+PerfDisableSharedMem -XX:G1HeapRegionSize=16M -XX:G1NewSizePercent=23 -XX:G1ReservePercent=20 -XX:SurvivorRatio=32 -XX:G1MixedGCCountTarget=3 -XX:G1HeapWastePercent=20 -XX:InitiatingHeapOccupancyPercent=10 -XX:G1RSetUpdatingPauseTimePercent=0 -XX:MaxTenuringThreshold=1 -XX:G1SATBBufferEnqueueingThresholdPercent=30 -XX:G1ConcMarkStepDurationMillis=5.0 -XX:G1ConcRSHotCardLimit=16 -XX:G1ConcRefinementServiceIntervalMillis=150 -XX:GCTimeRatio=99 -XX:AllocatePrefetchStyle=3

Aikar 著名的 Minecraft 服务器 G1GC 参数在客户端上运行良好,但有两个缺点:它们通过设置过高的值有效地限制了参数,导致某些客户端长时间卡顿;并且它们过于积极地收集旧代垃圾(因为客户端产生的垃圾远少于玩家多的服务器)。该参数与大名鼎鼎的 Aikar's G1GC 相似,但暂停时间更短、更频繁,G1 混合收集不那么激进,背景收集更激进。

G1GC (经典 Aikar's G1GC 改版适用于服务端)

-XX:+UseG1GC -XX:MaxGCPauseMillis=130 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=28 -XX:G1HeapRegionSize=16M -XX:G1ReservePercent=20 -XX:G1MixedGCCountTarget=3 -XX:InitiatingHeapOccupancyPercent=10 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=0 -XX:SurvivorRatio=32 -XX:MaxTenuringThreshold=1 -XX:G1SATBBufferEnqueueingThresholdPercent=30 -XX:G1ConcMarkStepDurationMillis=5 -XX:G1ConcRSHotCardLimit=16 -XX:G1ConcRefinementServiceIntervalMillis=150 -XX:AllocatePrefetchStyle=3

在服务器上,较长的暂停更容易被接受。该参数与 aikar 的参数非常接近,效果却更好。

注意:G1ConcRefinementServiceIntervalMillis 和 G1ConcRSHotCardLimit 已在 Java 21 中不存在,但由于我的基础参数包含了忽略不存在的参数,所以移除与否并不重要,即便不用 IgnoreUnrecognizedVMOptions 在 Java 21 平台上一般也就只会有个提示。

Yukiriri's G1GC (Java 11+ 最佳G1GC性能)

-XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:G1HeapRegionSize=4M -XX:G1NewSizePercent=100 -XX:G1MaxNewSizePercent=100 -XX:+AlwaysTenure -XX:-G1UseAdaptiveIHOP -XX:InitiatingHeapOccupancyPercent=80 -XX:G1MixedGCLiveThresholdPercent=95 -XX:MaxDirectMemorySize=1024G

直接取消了垃圾幸存区,年轻代回收后存活对象直接归为年老代,幸存区大小是影响暂停时间的一大因素,过高就会导致暂停变长,并且让 GC 不插手暗改 InitiatingHeapOccupancyPercent,尽可能减少不必要的Mixed GC,通过手动设定 InitiatingHeapOccupancyPercent 最大化减少了 Mixed GC 的开销。实测效果在上述两个 G1GC 参数之上,并且同时适用于客户端和服务端。

(研究中)因为可能让很多对象开directmemory自行管理内存,在某些情况下(模组/整合包)有概率会出现directmemory不断走高到峰值然后出现STW内存回收的情况,较大程度影响流畅性,这种情况下还是使用上面两个更传统的参数为好。

IU Shenandoah GC (Java 11+ 或 RedHat OJDK 8)

-XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGuaranteedGCInterval=1000000 -XX:AllocatePrefetchStyle=1

Shenandoah 是一个毫秒级暂停时间的垃圾收集器,吞吐量极高,在 MC 中表现尚可,但综合开销比 G1GC 要大很多,一般用得少,但在 1.12.2 和 1.7.10 等需求 Java 8 的版本里,使用 RedHat OpenJDK 加 Shenandoah CG 可以提供极佳的性能。如果使用 Shenandoah GC,至少应该有 6 核以上的 CPU,且分配更多的内存。

可选参数 -XX:ShenandoahGCHeuristics=static 目前正在测试中。

Non-Proactive ZGC (JDK 17+)

取消主动后的 ZGC 非常适合高内存/高核心数的服务器。根据 Nitwikit 的测试,它是吞吐量最高的 GC 之一。而且综合多方来源在硬件足够的情况下绝对不会卡顿,但是,它比其他垃圾收集器需要更多的内存和核心数,尤其是对于客户端的渲染线程开销而言,和 Shenandoah GC 应当一样至少在 6 核以上处理器的设备上启用,如果考虑最佳性能,则 8 个物理核心是必要的。启用它的方法如下:

-XX:+UseZGC -XX:-ZProactive -XX:AllocatePrefetchStyle=1

请注意:一定要分配更多内存,并且在 ConcGCThreads 中分配更多线程。

请注意:如果你的内存十分十分充足,可以加上 -XX:-ZUncommit 取消内存回馈到系统,进一步减少 CPU 在内存分配上的开销,但会造成极大的系统层级已提交内存。

(GZGC) Generational ZGC (JDK 21)

客户端运行帧数最高的 GC,没有之一,在任何测试中该 GC 的帧数都比其他的 GC 高一丢丢,而服务端上,绝对峰值性能和高压和环境并不如 Non-Proactive ZGC。但注意 GraalVM 21 中 Generational ZGC 不与 Graal JIT 编译器兼容,需要等到 24 以上的版本才行。同样需要更多的 CPU 核心与分配更多的内存。

-XX:+UseZGC -XX:+ZGenerational -XX:AllocatePrefetchStyle=1

请注意:一定要分配更多内存,并且在 ConcGCThreads 中分配更多线程。

请注意:如果你的内存十分十分充足,可以加上 -XX:-ZUncommit 取消内存回馈到系统,进一步减少 CPU 在内存分配上的开销,但会造成极大的系统层级已提交内存。

请注意:由于ZGC使用的彩色指针技术,Windows/Linux的任务管理器里都无法查看到完全正确的的内存占用

No-Proactive GZGC (JDK 21+ or GraalVM 24+)

我全都要的典范,其实在分代 ZGC 模式的基础上取消主动已经不会对客户端帧数产生更高额的开销了,无论在客户端还是服务端都运行十分优秀,但依旧不建议四核或更低配置用户使用,也需要分配更多内存。也正如上文所说 GraalVM 的 JVMCI 直到 24 才是兼容 GZGC,如果使用该参数最好等待 GraalVM 25 LTS 或者现在用 24 STS 版本。

-XX:+UseZGC -XX:+ZGenerational -XX:-ZProactive

请注意:在 JDK 24 已移除了 ZGenerational 这个 Flag,分代 ZGC 成为了 ZGC 默认模式,所以如果那个版本到来后,直接用上面的 Non-Proactive ZGC 参数也是可以的。

请注意:一定要分配更多内存,并且在 ConcGCThreads 中分配更多线程。

请注意:如果你的内存十分十分充足,可以加上 -XX:-ZUncommit 取消内存回馈到系统,进一步减少 CPU 在内存分配上的开销,但会造成极大的系统层级已提交内存。

请注意:由于ZGC使用的彩色指针技术,Windows/Linux的任务管理器里都无法查看到完全正确的的内存占用

Yukiriri 的内存紧凑 ZGC 参数 (低内存强烈推荐)

和很多人印象中不同的是,ZGC 既可以以大量内存为代价减少卡顿和延迟,也能够以一定吞吐量为代价极大程度上降低内存开销,在大型模组包的情况下最高可以降低到 1/4 内存使用量,比曾经 OpenJ9 还要离谱很多。主要是针对 16G 或 8G 内存用户游玩大型整合包,和曾经 J9 提升体验的原理一样,减少虚拟内存交换 (swap) 的开销,让更多的 CPU 可以好好负责游戏。

-XX:+UseZGC -XX:+ZGenerational -XX:-ZProactive -XX:ZCollectionIntervalMinor=0.95 -XX:ZUncommitDelay=2 -XX:MaxDirectMemorySize=1024G

原理是 ZGC 是垃圾清理彻底的 GC,该参数要求 ZGC 持续提交清理后空闲的内存返还给系统,虽然该过程会消耗一定 CPU,但也比更高代价的虚拟内存 swap 要好。

注意:GraalVM 21 JVMCI 不支持分代 ZGC,所以效果并不太好,只有分代 ZGC 下返提交内存给系统才能大幅降低内存开销。

注意:由于ZGC使用的彩色指针技术,Windows/Linux的任务管理器里都无法查看到完全正确的的内存占用

大页支持

内存大页可以提升应用程序的性能,在 JVM 这边是百分之十几到百分之三十几不等,即便是最不好的环境也会有非误差级别的优化,客户端和服务端都可以吃到,服务端可以提升 mspt 和区块光照性能,而客户端的 CPU 渲染帧也能吃到一些优化,应该是因为 CPU 绘图帧 DirectCall 的开销变低了,可谓是百利而无一害。

注意:在 Windows 系统上使用大页,必须要以管理员启动。并且在 Windows 上为大页 JVM 分配 8G 以上内存可能会崩溃,这种情况下加上 enable-mmagent -pagecombining 到参数末尾就可以解决了。

让我们先试一试是不是系统已经支持了这项功能,在控制台执行此命令

java -Xlog:gc+init -XX:+UseLargePages -Xmx1g -version

如果出现了以下字样,那么说明不完全兼容:

UseLargePages disabled, no large pages configured and available on the system.

那么就说明当前系统并不支持大页,不过不要急,可以试一下这一行命令:

java -Xlog:gc+init -XX:+UseTransparentHugePages -Xmx1g -version

如果看到 Large Page Support: Enabled (Transparent) ,表示你的系统支持透明大页。

但是如果你依然不支持还想要,可以看下面的攻略

Windows 10 专业版:https://www.chaoticafractals.com/manual/getting-started/enabling-large-page-support-windows

Windows 10 家庭版:https://awesomeprojectsxyz.blogspot.com/2017/11/windows-10-home-how-to-enable-lock.html?m=1

Windows 10 Home 教程的工具:https://gist.github.com/eyecatchup/0107bab3d92473cb8a3d3547848fc442

Linux:https://kstefanj.github.io/2021/05/19/large-pages-and-java.html

如果支持 LargePages,加上此参数

-XX:+UseLargePages -XX:LargePageSizeInBytes=2m

如果支持 TransparentHugePages,加上此参数

-XX:+UseTransparentHugePages

GC 线程数

-XX:ConcGCThreads=[某个数字]控制垃圾收集器允许使用的后台线程的最大数量,默认值为[逻辑(超线程)核心数 / 4]。最新版本的Java会根据需要减少gc线程数。

在某些情况下(尤其是使用ZGC或Shenandoah时),你可能想要将这个线程上限提高到默认值以上。我建议在大多数CPU上使用[实际(非超线程)核心数 - 2],但你可能需要调整这个参数。如果设置得太低,垃圾收集可能跟不上Minecraft的速度,游戏会出现卡顿和/或开始大量消耗RAM并崩溃。如果设置得太高,可能会减慢游戏速度,特别是如果你运行的是Java 8。可能最好保持在8以下(对于ZGC和Shenandoah,你可能可以使用10)。

不需要其他"线程"参数,如ParallelGCThreads或JVMCIThreads,因为它们在Java 8+中默认启用并具有良好的自动设置。

OpenJ9 参数(8-21通用)

OpenJ9 是完全重新设计的 JVM,拥有独立的垃圾回收系统,与 HotSpot JVM 的 G1GC、ZGC 等完全不同。存在大量的兼容性问题,如果单人玩家要拿来玩我觉得也就用在纯 Optifine 端比较合适。因为很早就存在 AOT 机制延续至今,所以通常预热周期较短。

-XX:+IdleTuningGcOnIdle -XX:+UseAggressiveHeapShrink -XX:+OmitStackTraceInFastThrow -XX:+UseFastAccessorMethods -XX:+OptimizeStringConcat -XX:+TieredCompilation -XX:+UseCompressedOops -Xshareclasses:allowClasspaths -Xshareclasses:cacheDir=./cache -Xaot -Xshareclasses -Xdisableexplicitgc -Xnoclassgc -Xverify:none -Xgcpolicy:balanced -Xaggressive -Xtune:virtualized -XX:ObjectAlignmentInBytes=256 -XX:SharedCacheHardLimit=800M -XX:InitialTenuringThreshold=5

我的参数包含了更多的优化措施,如果只是为了减少占用,那么就用 Nitwikit 的参数更好。

-XX:+IdleTuningGcOnIdle -XX:+UseAggressiveHeapShrink -XX:-OmitStackTraceInFastThrow -XX:+UseFastAccessorMethods -XX:+OptimizeStringConcat -Xshareclasses:allowClasspaths -Xshareclasses:cacheDir=./cache -Xaot -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=256 -Xshareclasses -XX:SharedCacheHardLimit=800M -Xtune:virtualized -XX:+TieredCompilation -XX:InitialTenuringThreshold=5 -Dlog4j2.formatMsgNoLookups=true -XX:-DisableExplicitGC

注意,HotSpot 的 G1GC 和 ZGC 都不适用于 OpenJ9,OpenJ9 使用 -Xgcpolicy 参数来指定垃圾回收策略。

四、其他 JDK 独特独门秘方

Dragonwell 11

待续

RedHat OpenJDK 8

待续

GraalVM EE 8/11 (不是太推荐)

待续

GraalVM CE

待续

Dragonwell 21

如果使用 G1GC,可以加上 -XX:+G1BarrierSimple,精简 G1 barrier逻辑, 减少 barrier 里的分支跳转, 增加编译优化机会, 提高吞吐率, 略微影响暂停时间。

通用 -XX:+UseCompactObjectHeaders 紧凑对象头,减少内存并提升 CPU 运行性能。

通用 -Dcom.alibaba.enableFastSerialization=true 快速序列化,提升 JDK 序列化性能。

Jebrains Runtime / SAPMachine Binary

其实就是 JDK 24 的参数,暂时还在研究中

五、其他值得考虑的东西

即将到来的 Java 25 LTS 相较于 Java 21 平台包含了大量新功能可以优化性能,比如类似 OpenJ9 的 AOT,缓存一定量运行上次 JIT 编译的代码,还有 Project Leyden、Project Lilliput 均可以从内存和 CPU 使用两个方面上优化 JVM 的性能,以及新的 Generational Shenandoah 垃圾回收器,或许也有自己发光发热的情况,并且 GraalVM 也演化了很多东西。

类似于 MC 每大概隔五代版本就是一个大的 Modded 狂欢(b1.7.3-1.2.5-1.7.10-1.12.2-1.18.2),JDK 的 LTS 几乎都是隔代大招 (8-17-25),和很多人刻板印象中 Java 缓慢不同的是,高版本 Java 平台性能是相当优秀的,我也期待未来 MC 能更好利用 JVM 的性能和优化。

毫无价值的参考

https://whichjdk.com/ 充满了政治正确,除了 GraalVM 确实好用外,推荐和否认的理由均毫无价值。

参考资料

https://www.hqshi.cn/info/knowledge/mc-jdk-test

https://jdkcomparison.com/

网页链接​

https://blog.binklac.com/e6ad4dc21152/

https://nitwikit.8aka.org/Java/optimize/jvm

https://steinborn.me/posts/tuning-minecraft-for-openj9/

https://developer.aliyun.com/article/1079907

https://github.com/Yukiriri/OMCF

https://github.com/MeowIce/meowice-flags

https://github.com/8aka-Team/Test-Java

https://github.com/Mukul1127/Minecraft-Java-Flags

https://github.com/Mukul1127/Minecraft-Performance-Flags-Benchmarks

https://github.com/Arborsm/Minecraft-Java-Flags

https://github.com/brucethemoose/Minecraft-Performance-Flags-Benchmarks

https://github.com/DataDalton/Minecraft-Performance-Guide/blob/main/Java%20Arguments/README.md

https://github.com/DataDalton/Minecraft-Performance-Guide/blob/main/Large%20Page%20files/README.md

https://archives.mcbbs.co/read.php?tid=899289

https://archives.mcbbs.co/read.php?tid=847020

https://archives.mcbbs.co/read.php?tid=1232993

https://www.reddit.com/r/feedthebeast/comments/as6p87/java_vms_and_you_how_to_reduce_your_ram_and_cpu/

https://www.reddit.com/r/feedthebeast/comments/uz21wc/graalvm_speeds_up_modded_minecraft/