Aikar's 旗帜参数在 12 GB 内存分界点发生变化 — 其中五个,一个减小
将 4 GB 内存的旗帜参数复制到 16 GB 服务器上会导致五个参数出错。本文将详细说明是哪五个参数,以及模组服务器和原版服务器分别在多少玩家数量时会达到这个分界点。
Aikar's 旗帜参数是社区公认的 Paper 服务器 JVM 参数,通常被视为一个整体进行复制。但它们并非一个整体:在二十个参数中,有五个参数会根据你的堆内存是否超过 12 GB 而变化。将小堆内存参数集粘贴到大堆内存服务器上,是运行“推荐旗帜参数”却未能正确配置的最常见方式。
变化的五个参数
| 旗帜参数 | 低于 12 GB | 12 GB 及以上 |
|---|---|---|
-XX:G1NewSizePercent | 30 | 40 |
-XX:G1MaxNewSizePercent | 40 | 50 |
-XX:G1HeapRegionSize | 8M | 16M |
-XX:G1ReservePercent | 20 | 15 |
-XX:InitiatingHeapOccupancyPercent | 15 | 20 |
G1ReservePercent 是唯一一个减小的参数。五个参数中有四个随着堆内存大小增加而增加,而这一个却减小了,这就是为什么半生不熟地“为大服务器调高参数”会产生错误而非仅仅是次优参数集的原因。它预留了一部分堆内存以防止内存回收失败,而更大的堆内存需要更小的比例来保持相同的绝对预留空间。
其余十三个 -XX: 参数在所有堆内存大小下都保持不变 — -XX:+UseG1GC、-XX:MaxGCPauseMillis=200、-XX:+AlwaysPreTouch、-XX:SurvivorRatio=32、-XX:MaxTenuringThreshold=1 等参数都不会改变。只有 -Xms 和 -Xmx 会根据堆内存大小本身进行调整。
12 GB 分界点实际落在何处
此页面上的生成器会根据你的玩家数量来确定堆内存大小:
GB = clamp( ceil( (modded ? 2.5 : 1) × (2 + players / 12) ), 2, 32 )
模组服务器的预算是原版服务器的 2.5 倍,这个系数决定了谁会看到大堆内存分支:
| 玩家数量 | 原版 | 模组 |
|---|---|---|
| 10 | 3 GB | 8 GB |
| 20 | 4 GB | 10 GB |
| 29 | 5 GB | 12 GB ← 模组服务器在此处跨越 |
| 50 | 7 GB | 16 GB |
| 100 | 11 GB | 26 GB |
| 109 | 12 GB ← 原版服务器在此处跨越 | 28 GB |
模组服务器在 29 名玩家时达到大堆内存参数要求。而原版服务器直到 109 名玩家才达到。因此,对于大多数运行原版 Paper 的玩家来说,小堆内存参数集是永久正确的选择 — 而对于大多数运行模组服务器的玩家来说,它比他们预期的要早得多就不再正确了。
该公式中值得注意的两个限制
它从不推荐超过 32 GB。原版服务器在 349 名玩家时达到上限并保持不变。这并非四舍五入的误差 — 超过大约 32 GB 后,JVM 会丢失压缩对象指针(compressed object pointers),堆内存中的每个引用都会变大,因此更多的 RAM 可能意味着更少可用的堆内存。超过这个点进行扩展是第二台服务器的工作,而不是更大的服务器。
它从不推荐低于 2 GB,即使是单人玩家,因为下限是服务器软件而不是玩家数量。
无论公式怎么说:不要将服务器的所有内存都分配给 JVM。-Xms 和 -Xmx 在这里被特意设置为相同的值 — 固定堆内存可以避免 JVM 在负载下调整大小 — 这意味着你选择的数字会被立即永久占用。为操作系统留下 1-2 GB,这样它就不必与你争夺内存。