Оптимизация JVM-флагов Java для Minecraft-серверов: полное руководство
Каждый Minecraft-сервер работает на Java Virtual Machine, и настройки JVM по умолчанию не предназначены для игровых серверов. Они рассчитаны на универсальные приложения, где пропускная способность важнее задержки. Для Minecraft-сервера задержка решает все. Пауза сборщика мусора в 200мс означает видимый лаг-спайк, который игроки чувствуют моментально. В MineGuard мы настраивали JVM для сотен серверов, и в этом руководстве делимся всем, что знаем.
Что на самом деле делают JVM-флаги
Когда вы запускаете сервер командой java -jar server.jar, JVM использует настройки по умолчанию для управления памятью, сборки мусора и оптимизации во время выполнения. Эти настройки рассчитаны на универсальную нагрузку. Minecraft не универсален. Он создает и отбрасывает миллионы мелких объектов каждую секунду (обновления блоков, тики сущностей, буферы пакетов), и ему нужен стабильный тайминг тиков без пауз длиннее 50мс.
JVM-флаги позволяют переопределить эти настройки. Они контролируют объем памяти JVM, какой сборщик мусора работает, насколько агрессивно он собирает, и десятки других параметров. Правильная комбинация может сократить паузы GC на 80% и стабилизировать TPS на твердых 20.
Основы памяти: -Xmx и -Xms
Два самых важных флага - -Xmx (максимальный размер кучи) и -Xms (начальный размер кучи). Всегда ставьте их одинаковыми:
-Xms8G -Xmx8G
Почему одинаковыми? Когда -Xms меньше -Xmx, JVM стартует с меньшим объемом памяти и наращивает кучу динамически. При каждом увеличении JVM ставит процесс на паузу для перераспределения. Выставив одинаковые значения, вы полностью убираете эти паузы. JVM выделяет всю память при старте и больше не изменяет размер.
Сколько RAM нужно вашему серверу?
Практические рекомендации по количеству игроков и сложности мира:
- 1-20 игроков: 2-4 ГБ
- 20-50 игроков: 4-6 ГБ
- 50-100 игроков: 6-8 ГБ
- 100-200 игроков: 8-12 ГБ
- 200+ игроков: 12-16 ГБ
Эти цифры предполагают Paper или Purpur с умеренным количеством плагинов (15-30). Сильно модифицированные серверы (Forge/Fabric с 100+ модами) могут потребовать на 2-4 ГБ больше.
Типичная ошибка: выделение слишком много RAM. Если у вас доступно 32 ГБ, не ставьте -Xmx32G. Сборщик мусора должен сканировать всю кучу при сборке. Больше куча - длиннее паузы GC. Дайте серверу столько, сколько ему нужно, плюс 20-30% запаса, не больше.
Сборка мусора: сердце настройки JVM
Сборка мусора (GC) - это процесс поиска и освобождения памяти, которую ваш сервер больше не использует. JVM делает это автоматически, но способ, которым это происходит, имеет огромное значение. Во время паузы GC ваш сервер буквально прекращает обрабатывать тики.
G1GC (Garbage First Garbage Collector)
G1GC - рекомендуемый сборщик мусора для Minecraft-серверов и основа флагов Aikar. Он делит кучу на регионы и собирает те, в которых больше всего мусора (отсюда и название). Такой подход дает предсказуемое время пауз.
Почему G1GC хорошо подходит для Minecraft:
- Целевое максимальное время паузы (настраивается через
MaxGCPauseMillis) - Эффективно работает с кучами от 2 до 16 ГБ
- Выполняет основную работу конкурентно, не останавливая сервер
- Отлично справляется с нагрузками, создающими много короткоживущих объектов (а Minecraft делает это постоянно)
ZGC (Z Garbage Collector)
ZGC - сборщик с низкой задержкой, рассчитанный на субмиллисекундные паузы. Звучит идеально? Не совсем. ZGC жертвует пропускной способностью ради времени пауз. Он использует больше CPU для достижения таких маленьких пауз, и на серверах с ограниченным количеством ядер эти накладные расходы могут навредить TPS.
ZGC стоит попробовать, если:
- У вас 8+ ядер CPU, выделенных для сервера
- Куча 16 ГБ или больше
- Вы используете Java 21+ (ZGC значительно улучшился в последних версиях)
Для большинства серверов G1GC с настройками Aikar будет работать лучше ZGC.
Shenandoah
Shenandoah - еще один сборщик с низкими паузами, похожий по целям на ZGC, но с другим подходом. Он доступен в сборках OpenJDK (не Oracle JDK). Как и ZGC, он обменивает CPU на время пауз и лучше всего работает на серверах с достаточным количеством ядер.
Наша рекомендация: начните с G1GC. Переключайтесь на ZGC или Shenandoah только если вы профилировали сервер через Spark и подтвердили, что паузы GC - ваше узкое место, и у вас есть запас по CPU.
Флаги Aikar: золотой стандарт
Флаги Aikar - это набор JVM-флагов, специально настроенных для Minecraft-серверов. Они проверены на серверах с тысячами игроков и оттачивались годами. Разберем, что делает каждый флаг:
Разбор основных флагов
-XX:+UseG1GC
Включает сборщик мусора G1 вместо стандартного.
-XX:+ParallelRefProcEnabled
Обрабатывает ссылочные объекты (WeakReferences, SoftReferences) параллельно, а не последовательно. Плагины Minecraft создают много таких объектов.
-XX:MaxGCPauseMillis=200
Указывает G1GC целевую максимальную паузу в 200мс. Сборщик подстраивает свое поведение, чтобы оставаться в рамках этой цели.
-XX:+UnlockExperimentalVMOptions
Включает экспериментальные флаги, недоступные по умолчанию. Необходим для некоторых параметров ниже.
-XX:+DisableExplicitGC
Запрещает плагинам вызывать System.gc() вручную. Некоторые плохо написанные плагины делают это, вызывая ненужные полные паузы GC.
-XX:G1NewSizePercent=30
-XX:G1MaxNewSizePercent=40
Выделяет 30-40% кучи под молодое поколение (куда попадают новые объекты). Minecraft создает тонны короткоживущих объектов, поэтому большее молодое поколение означает менее частые сборки.
-XX:G1HeapRegionSize=8M
Устанавливает размер каждого региона G1 в 8 МБ. Большие регионы уменьшают накладные расходы для больших куч, но могут увеличить паузы для маленьких. 8M - оптимальный баланс для серверов с 4-16 ГБ.
-XX:G1ReservePercent=20
Резервирует 20% кучи как буфер безопасности. Это предотвращает те самые страшные полные GC-паузы "to-space exhausted", которые случаются, когда у сборщика заканчиваются свободные регионы.
-XX:G1MixedGCLiveThresholdPercent=90
Собирает регион, только если 90% или более его содержимого - мусор. Это уменьшает объем живых данных, которые нужно копировать при сборке.
-XX:InitiatingHeapOccupancyPercent=15
Запускает конкурентный цикл GC, когда занято 15% кучи. Это агрессивно (по умолчанию 45%), но означает, что сборщик начинает работу рано и имеет больше времени завершить без паузы.
-XX:SurvivorRatio=32
Уменьшает размер области выживших. В нагрузках Minecraft объекты либо умирают мгновенно, либо живут долго (как загруженные чанки). Меньше необходимости держать объекты между сборками.
-XX:+PerfDisableSharedMem
Отключает запись статистики GC в файл общей памяти. Это убирает периодические спайки задержки из-за файловых операций.
-XX:MaxTenuringThreshold=1
Продвигает объекты в старое поколение после всего 1 цикла GC. В сочетании с большим молодым поколением это хорошо работает для паттерна аллокаций Minecraft.
GraalVM: альтернативная среда выполнения
GraalVM - альтернативный дистрибутив JDK с продвинутым JIT-компилятором. Для Minecraft-серверов GraalVM может дать 5-15% лучшую производительность по сравнению с обычным OpenJDK, особенно в вычислительно тяжелых сценариях, таких как генерация мира и обработка редстоуна.
Преимущества GraalVM:
- Более агрессивная JIT-оптимизация
- Лучший инлайнинг вызовов методов
- Улучшенный анализ побегов (уменьшает аллокации в куче)
- Работает как замена OpenJDK без изменений
Чтобы использовать GraalVM, скачайте его с официального сайта и замените вашу установку Java. Все флаги Aikar работают с GraalVM. Также можно добавить специфические флаги:
-XX:+UseJVMCICompiler
-XX:+EagerJVMCI
Примечание: GraalVM Community Edition бесплатен. Enterprise Edition предлагает дополнительные оптимизации, но требует лицензию.
Большие страницы памяти
Большие страницы (Large Pages, они же Huge Pages) позволяют JVM использовать страницы памяти по 2 МБ вместо стандартных 4 КБ. Это уменьшает промахи TLB (Translation Lookaside Buffer) и улучшает производительность доступа к памяти на 5-10%.
Для включения больших страниц:
- Настройте ОС (Linux):
echo "vm.nr_hugepages=4096" >> /etc/sysctl.conf && sysctl -p - Добавьте JVM-флаг:
-XX:+UseLargePages
Количество нужных huge pages равно размеру кучи, разделенному на 2 МБ. Для кучи 8 ГБ: 8192 / 2 = 4096 страниц.
Большие страницы требуют настройки на уровне root и наиболее полезны на выделенных серверах. Если вы на хостинге, пропустите этот шаг.
Дедупликация строк
Java-строки с одинаковым содержимым можно дедуплицировать для экономии памяти. Это особенно полезно для Minecraft, потому что в памяти существует много идентичных строк (названия предметов, типы блоков, сообщения чата).
-XX:+UseStringDeduplication
Этот флаг почти не нагружает CPU и может уменьшить потребление памяти на 5-10%. Работает только с G1GC, который и используют флаги Aikar.
Готовые наборы флагов
Вот готовые к использованию наборы флагов для разных размеров серверов. Копируйте целиком и используйте как команду запуска.
Маленький сервер (2 ГБ RAM, 1-20 игроков)
java -Xms2G -Xmx2G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=4M -XX:G1ReservePercent=20 -XX:G1MixedGCLiveThresholdPercent=90 -XX:InitiatingHeapOccupancyPercent=15 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -XX:+UseStringDeduplication -jar server.jar --nogui
Примечание: G1HeapRegionSize установлен на 4M для сервера с 2 ГБ (маленькая куча выигрывает от меньших регионов).
Средний сервер (4 ГБ RAM, 20-50 игроков)
java -Xms4G -Xmx4G -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:G1MixedGCLiveThresholdPercent=90 -XX:InitiatingHeapOccupancyPercent=15 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -XX:+UseStringDeduplication -jar server.jar --nogui
Большой сервер (8 ГБ RAM, 50-100 игроков)
java -Xms8G -Xmx8G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=40 -XX:G1MaxNewSizePercent=50 -XX:G1HeapRegionSize=16M -XX:G1ReservePercent=20 -XX:G1MixedGCLiveThresholdPercent=90 -XX:InitiatingHeapOccupancyPercent=15 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -XX:+UseStringDeduplication -XX:+UseLargePages -jar server.jar --nogui
Примечание: увеличены G1NewSizePercent до 40 и G1MaxNewSizePercent до 50 для большей кучи. Добавлен UseLargePages (требует настройки ОС).
Корпоративный сервер (16 ГБ RAM, 200+ игроков)
java -Xms16G -Xmx16G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=40 -XX:G1MaxNewSizePercent=50 -XX:G1HeapRegionSize=16M -XX:G1ReservePercent=20 -XX:G1MixedGCLiveThresholdPercent=90 -XX:InitiatingHeapOccupancyPercent=15 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -XX:+UseStringDeduplication -XX:+UseLargePages -jar server.jar --nogui
Для серверов с 16 ГБ можно также протестировать ZGC как альтернативу:
java -Xms16G -Xmx16G -XX:+UseZGC -XX:+AlwaysPreTouch -XX:+DisableExplicitGC -XX:+UseLargePages -jar server.jar --nogui
ZGC требует меньше настроечных флагов, потому что подстраивается сам. Протестируйте обе конфигурации и сравните через профайлер Spark.
Типичные ошибки
Ошибка 1: слишком много RAM. Куча 32 ГБ на сервере с 20 игроками даст вам более длинные паузы GC, а не лучшую производительность. Сборщик мусора должен сканировать всю кучу. Держите размер оптимальным.
Ошибка 2: неправильный сборщик мусора. CMS (Concurrent Mark Sweep) был популярен годами, но его удалили в Java 14. Если ваш скрипт запуска все еще содержит -XX:+UseConcMarkSweepGC, обновите его немедленно. G1GC - правильный выбор.
Ошибка 3: разные -Xms и -Xmx. Установка -Xms512M -Xmx8G означает, что JVM будет десятки раз изменять размер кучи по мере загрузки сервера, вызывая подтормаживания и паузы в первые минуты работы.
Ошибка 4: использование Java 8. Java 8 устарела. Каждая новая версия Java приносит улучшения GC, патчи безопасности и оптимизации производительности. Используйте минимум Java 21 LTS. В Java 21 G1GC и ZGC значительно улучшены по сравнению со старыми версиями.
Ошибка 5: игнорирование логов GC. Добавьте -Xlog:gc*:file=gc.log:time к вашим флагам. Это создаст лог-файл, показывающий, что именно делает сборщик мусора. Используйте инструменты GCViewer или GCEasy для анализа.
За пределами JVM: производительность сети тоже важна
Вы можете настроить JVM до совершенства, но если ваш сервер под DDoS-атакой или бот-флудом, это все не имеет значения. Производительность сервера и производительность сети - две стороны одной монеты.
В MineGuard мы берем на себя сетевую сторону. Наш фильтр работает на уровне пакетов, верифицируя соединения и блокируя вредоносный трафик до того, как он достигнет вашего сервера. Накладные расходы? Менее 1мс добавленной задержки. Ваши игроки не заметят нашу защиту, но они точно заметят отсутствие лаг-спайков от бот-флудов, перегружающих сервер.
Оптимизируйте JVM-флаги для внутренней производительности. Внешние угрозы оставьте нам. Вместе это сервер, который держит стабильные 20 TPS при любых условиях.
Protégez votre serveur contre les attaques DDoS
Protection gratuite avec configuration en 5 minutes. 1 To de bande passante inclus.
Essayer gratuitementArticles connexes
Skript: основы скриптинга для админов Minecraft серверов (2026)
Skript позволяет писать логику сервера на почти английском языке без Java. Установка, синтаксис, события, команды, переменные, аддоны skBee и skript-yaml, типичные ошибки и как их избежать.
OneBlock SMP сервер Minecraft: полный гайд по настройке режима «один блок»
Поднимаем OneBlock SMP на Paper 1.21 с BentoBox: установка, фазы, кастомизация YAML, команды, SMP-составляющая, бэкап и сезоны.
Как подключить Minecraft сервер к MineGuard: пошаговая инструкция
Подробная инструкция по подключению вашего Minecraft сервера к защите MineGuard. Регистрация, настройка сети, домен, proxy protocol, файрвол. Весь процесс занимает около 5 минут.