TeaHost
Minecraftminecraftоптимизацияjvm5 мин. чтения

Aikar's flags для Minecraft: флаги JVM для сервера

Aikar's flags для Minecraft: готовая строка запуска, разбор флагов G1GC, настройка под 4-12 ГБ памяти и что менять для крупных модпаков.

Кратко

Aikar's flags — набор параметров JVM для G1GC, который убирает периодические фризы сервера Minecraft: -XX:+UseG1GC, MaxGCPauseMillis=200, G1NewSizePercent=30, G1HeapRegionSize=8M и другие. Ставьте -Xms равным -Xmx и оставляйте 1–1,5 ГБ памяти тарифа вне кучи; от 12 ГБ используйте вариант с регионами 16M.

Если сервер время от времени замирает на секунду-другую при нормальном TPS в среднем, дело почти всегда в сборщике мусора. Java по умолчанию настроена на приложения, которым можно паузу на 200–500 мс, а Minecraft на такой паузе теряет 4–10 тиков — игроки видят это как рывок. Aikar's flags для Minecraft — набор параметров JVM, который меняет поведение G1GC так, чтобы паузы стали короткими и предсказуемыми.

Разберу готовую строку запуска, смысл каждого флага и то, что нужно поменять под ваш объём памяти.

Что такое Aikar's flags и зачем они Minecraft-серверу

Набор собрал Aikar, один из разработчиков Paper, ещё во времена 1.8, и с тех пор он остаётся стандартом де-факто. Идея простая: заставить сборщик мусора работать чаще и мелкими порциями вместо редких длинных остановок.

Три ключевых решения внутри набора:

  1. Фиксированный размер кучи — -Xms равен -Xmx, JVM не тратит время на расширение и сжатие
  2. Ранний старт сборки — GC начинает работу при заполнении 30–40%, а не 90%, поэтому не приходится чистить всё сразу
  3. Мелкие регионы — куча делится на блоки по 8–32 МБ, каждая сборка обрабатывает малую часть

Прирост среднего TPS от флагов небольшой, обычно 0,2–0,5. Главный эффект в другом: пропадают периодические подвисания, а 1% и 5% худших тиков (то, что видно в /spark tps) улучшаются заметно.

Готовая строка запуска

Для памяти от 4 до 12 ГБ (Java 17 и новее). Строка совпадает с рекомендацией PaperMC, разработчики там же подробно объясняют каждый флаг:

код
java -Xms6G -Xmx6G --add-modules=jdk.incubator.vector -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true -jar server.jar nogui

-Xms6G -Xmx6G меняете под свой тариф. PaperMC советует ставить -Xmx на 1000–1500 МБ меньше памяти тарифа: Java и системе нужна память сверх кучи. Как выбрать значение, разобрано в разделе про выделение памяти серверу.

В панели управления строка вставляется в поле параметров запуска (Java Flags / JVM Arguments). При запуске через systemd или screen — в скрипт старта; порядок описан в статье про автозапуск сервера.

Вариант для 12 ГБ и больше

При большой куче регионы должны быть крупнее, а молодое поколение — меньше в процентах:

код
-XX:G1NewSizePercent=40 -XX:G1MaxNewSizePercent=50 -XX:G1HeapRegionSize=16M -XX:G1ReservePercent=15 -XX:InitiatingHeapOccupancyPercent=20

Остальные флаги остаются теми же. Такой профиль нужен крупным модпакам — установка модов и требования к памяти описаны в разделах про моды Forge и Fabric.

Разбор основных флагов

-XX:+UseG1GC — включает сборщик G1. Это база всего набора; без него остальные флаги бессмысленны.

-XX:MaxGCPauseMillis=200 — целевая длительность паузы. Не гарантия, а ориентир для JVM. Снижать до 50 бесполезно: сборщик начнёт работать чаще и съест больше CPU, не уложившись в цель.

-XX:+AlwaysPreTouch — JVM при старте физически резервирует всю память. Сервер стартует на несколько секунд дольше, зато потом не спотыкается на выделении страниц. На хостинге с гарантированной памятью — обязательно.

-XX:+DisableExplicitGC — игнорирует вызовы System.gc() из кода плагинов. Некоторые плагины дёргают полную сборку вручную, и каждый такой вызов — заметная пауза.

-XX:G1NewSizePercent=30 и -XX:G1MaxNewSizePercent=40 — доля кучи под молодое поколение. У Minecraft почти весь мусор короткоживущий (энтити, пакеты, временные объекты), поэтому молодому поколению нужно много места.

-XX:InitiatingHeapOccupancyPercent=15 — при 15% заполнения начинается фоновый цикл сборки. Стандартное значение 45 приводит к тому, что GC берётся за работу поздно и вынужден делать длинную паузу.

-XX:+ParallelRefProcEnabled — параллельная обработка ссылок, помогает при большом числе энтити.

-XX:MaxTenuringThreshold=1 — объекты быстро переезжают в старое поколение вместо многократного копирования между survivor-областями.

-XX:+PerfDisableSharedMem — отключает файл со статистикой JVM в /tmp. Мелочь, но на нагруженном диске убирает редкие фризы.

--add-modules=jdk.incubator.vector — включает векторный API Java, который используют некоторые форки Paper (например, Purpur). В официальной строке PaperMC его нет; на чистом Paper флаг можно не указывать.

Чего этот набор не делает

Флаги не увеличивают производительность самой игры. Они не поднимут TPS, если:

  • Сервер упирается в однопоточную производительность процессора
  • На карте стоит ферма с тысячами энтити
  • Плагин с утечкой памяти постепенно съедает кучу
  • Мало памяти в принципе — тогда GC работает непрерывно и никакие флаги не помогут

Порядок диагностики: сначала посмотрите /spark tps и /spark profiler, потом чините конфиги (bukkit.yml, spigot.yml, Paper), и только потом флаги. Разбор конфигов — в разделах про bukkit.yml и spigot.yml, а общий чек-лист — в статье как оптимизировать сервер Minecraft.

Проверка, что флаги применились

Первый способ — команда /spark health покажет используемый сборщик и статистику пауз G1. Средняя пауза 5–25 мс — норма. Стабильно за 100 мс — либо флаги не применились, либо памяти не хватает.

Второй — посмотреть строку запуска процесса на машине с root-доступом:

код
ps aux | grep java

Частые ошибки

-Xms меньше -Xmx. Классика. JVM будет расширять кучу на ходу, и каждое расширение — пауза. Значения должны совпадать.

Флаги указаны после -jar. JVM читает параметры до имени jar-файла; всё, что идёт после, передаётся серверу как аргументы и игнорируется.

Куча на весь объём тарифа. -Xmx, равный памяти тарифа, не оставляет места самой Java и системе — процесс рано или поздно убьёт OOM-killer. А куча сильно больше нужного не вредит G1, но и не ускоряет сервер: после определённого объёма прироста нет, и вы платите за неиспользуемую память. Ориентиры по размеру — в статье сколько RAM нужно Minecraft-серверу.

Устаревшие флаги с CMS. Наборы времён Java 8 с -XX:+UseConcMarkSweepGC на Java 17 просто не запустятся: этот сборщик удалён.

ZGC вместо G1. ZGC даёт очень короткие паузы, но на Minecraft чаще проигрывает по общей пропускной способности, особенно на куче меньше 16 ГБ. Экспериментировать имеет смысл только на больших сборках и с замерами до/после.

Коротко

Возьмите готовую строку, подставьте свой -Xms/-Xmx одинаковыми значениями, вставьте в параметры запуска и перезапустите сервер. Через сутки сравните /spark health: средняя пауза GC должна уложиться в 25 мс, а рывки — пропасть.

Если после этого паузы остались длинными, серверу не хватает памяти или ядер — подобрать конфигурацию можно на странице тарифов.