MAATRIX GAMES / Блог / Project Zomboid: память сервера переполняется

Project Zomboid: память сервера переполняется

MAATRIX GAMES

Сервер Project Zomboid поднялся на 6 ГБ и первую неделю жил спокойно, а через месяц активного прохождения процесс ProjectZomboid64 съедает всю выделенную кучу, игроков начинает откидывать с ошибками, а рестарт помогает на пару дней и снова возвращается к тому же. Это не разовый баг конкретно вашей сборки — у Zomboid-серверов рост потребления памяти со временем встроен в саму механику мира, и с этим можно работать осмысленно, а не гадать, докупать RAM вслепую. Разберём, откуда берётся рост, как настроить кучу Java правильно и какие рычаги реально снижают нагрузку.

Почему память сервера растёт со временем

Java-процесс сервера ограничен не объёмом физической RAM машины, а параметром -Xmx — максимальным размером кучи, который вы задали явно. Если куча забивается быстрее, чем вы ожидали, дело не в "утечке" в бытовом смысле, а в том, что мир объективно накапливает данные, которые движок обязан держать в памяти.

Три главных источника роста:

  • Разведанная территория. Project Zomboid хранит подробное состояние только для клеток карты (ячеек примерно 300×300 тайлов), которые хотя бы раз попадали в зону видимости игроков. Свежий мир, где компания сидит в одном городке, ест заметно меньше памяти, чем тот же сервер через месяц, когда игроки успели изъездить половину карты на машинах — каждая новая разведанная клетка добавляет вес в рантайме, и сервер это состояние не выгружает сам по себе просто потому, что игроки уехали дальше.
  • Популяция зомби по клеткам. Zomboid не считает всех зомби на карте одинаково подробно. Рядом с игроками зомби симулируются как полноценные сущности — путь, звук, повреждения, анимация. В клетках, которые давно не посещались, популяция держится как "виртуальное" число, которое разворачивается в реальных зомби только когда туда снова кто-то заходит. Проблема в том, что число разведанных и хотя бы недавно посещённых клеток со временем только растёт, а вместе с ним растёт и объём клеток с активной, подробной симуляцией.
  • Накопление предметов и трупов в мире. Каждый брошенный контейнер, разбитая машина, труп зомби или выжившего — это объект, который сервер держит в памяти, пока клетка активна. На активно играющем сервере без чисток список таких объектов только пополняется.

Официального технического разбора точных цифр The Indie Stone не публиковали, так что дальше — не измеренные бенчмарки, а практика админов, которые держат серверы неделями: заметный рост потребления за 2-4 недели активной игры без перезапуска — обычное дело, закладывайте это в план по RAM сразу, а не воспринимайте как поломку.

Как отличить постепенный рост от разового скачка

Прежде чем что-то настраивать, стоит понять, с чем вы имеете дело: с плавным ростом за недели или с разовым скачком за минуты от конкретного события (массовая зачистка орды, взрыв, загрузка тяжёлого мода).

Быстрая проверка в реальном времени:

htop

Ищите процесс ProjectZomboid64 (или java, если имя процесса не отображается явно), смотрите колонку RES — это резидентная память, реально занятая в RAM, а не декларированный лимит кучи.

Для картины по времени — снимайте показания раз в час скриптом:

#!/bin/bash
# pz-mem-log.sh
ts=$(date '+%Y-%m-%d %H:%M:%S')
mem=$(ps -o rss= -C ProjectZomboid64 | tr -d ' ')
echo "$ts;${mem} KB" >> /home/pzuser/mem-usage.log

Добавьте в crontab пользователя pzuser:

0 * * * * /home/pzuser/pz-mem-log.sh

Через пару недель у вас будет реальный график роста именно вашего мира, а не чужие цифры из форума. Резкий скачок за секунды-минуты, а не плавная линия часами — отдельная история, плановый рестарт её не лечит, ищите конкретное событие (массовый спавн через админ-команду, загрузка тяжёлого мода, крупный взрыв).

Поднять сервер Project Zomboid за пару минут

Готовый образ MAATRIX GAMES: NVMe, AMD EPYC, DDoS-защита, панель управления. Локации UK, US, RU. Оплата картой РФ, СБП или криптой.

Создать сервер

Лимит кучи Java: -Xmx и ProjectZomboid64.json

Сервер запускается через start-server.sh в корне установки (~/pzserver/, см. статью про подъём сервера Project Zomboid), но реальные параметры JVM, включая размер кучи, задаются в соседнем файле:

~/pzserver/ProjectZomboid64.json

Внутри — список аргументов JVM (vmArgs), среди которых ищите строки с -Xms (стартовый размер кучи) и -Xmx (максимальный):

{
  "vmArgs": [
    "-Xms2g",
    "-Xmx8g",
    "-Dzomboid.steam=1",
    "-Dzomboid.znetlog=1"
  ]
}

Дефолтное значение -Xmx отличается между сборками игры — на разных версиях встречались и 2 ГБ, и 8 ГБ по умолчанию, так что не полагайтесь на память "как было при установке" — откройте файл и проверьте текущее число сами.

Логика настройки простая: -Xmx должен быть заметно меньше физической RAM машины, а не равен ей — оставляйте 1-2 ГБ на операционную систему, SSH-сессию и фоновые процессы. Если поставить -Xmx, равный всей RAM VPS, сервер рано или поздно упрётся в OOM-килл ядра ОС, а не в аккуратную ошибку Java, и будет падать без внятной строки в логе.

Ориентир для соотношения RAM машины и -Xmx:

RAM машиныРазумный -Xmx
6 ГБ4-4.5g
8 ГБ6-6.5g
12 ГБ9-10g
16 ГБ13-14g

После правки -Xmx и -Xms сервер нужно перезапустить полностью — на лету JVM-параметры не подхватываются:

sudo systemctl restart pzserver

Если у вас нет отдельного -Xms, стартовый размер кучи по умолчанию может быть заметно меньше -Xmx — это не проблема, Java просто расширяет кучу по мере надобности, но резкие расширения кучи в момент наплыва зомби иногда дают короткую просадку тика. Если сервер держит стабильно высокую нагрузку, есть смысл поставить -Xms близко к -Xmx, чтобы куча не дёргалась туда-сюда.

SandboxVars и другие настройки, которые влияют на память

Часть настроек в servertest_SandboxVars.lua (см. структуру конфигов в статье про установку сервера) прямо влияет на то, сколько объектов серверу приходится держать в памяти одновременно. Отдельно стоит сразу закрыть один частый источник путаницы: параметр MinutesPerPage управляет только скоростью чтения книг навыков персонажем и к памяти сервера отношения не имеет, несмотря на то, что название иногда наводит на мысль о "странице" памяти — не тратьте время на его подбор в контексте этой проблемы.

Настройки, которые реально работают на снижение нагрузки:

ZombieConfig = {
    Population = 2,   -- ниже значение — меньше зомби, которых сервер держит в памяти и считает
}

RespawnHours = 72          -- как часто пересоздаётся популяция в клетках без игроков
RespawnUnseenHours = 16    -- порог "давно не видели" перед пересозданием
  • Population. Прямой множитель числа зомби на карте. Снижение с "Insane"/"High" до "Normal" (или числового аналога) убирает не только нагрузку на CPU от симуляции путей, но и объём памяти под сами сущности — это самый быстрый рычаг, если сервер уже переполнен и нужно снять остроту здесь и сейчас.
  • RespawnHours / RespawnUnseenHours. Управляют, как часто пересоздаётся население в клетках, которые давно не посещались. Слишком короткий интервал держит больше клеток "активными" одновременно за счёт постоянного обновления; слишком длинный — не даёт зомби-популяции восстанавливаться после зачисток, но и не разгружает память заметно, потому что клетка всё равно продолжает числиться разведанной.

Точные числа — вопрос вкуса и размера группы: хардкорным RP-серверам обычно важнее держать Population высоким, казуальным компаниям на 2-4 человека проще один раз срезать популяцию и не думать об этом до конца сезона.

Отдельный источник нагрузки, который не лечится через SandboxVars, — моды. Каждый установленный мод с новыми предметами, зданиями или NPC добавляет объекты в рантайм; если сервер упирается в память с большим модлистом, начните с самых "тяжёлых" по контенту модов, а не срезайте случайные настройки — как модлист вообще влияет на сервер, разобрано в статье про установку модов через Steam Workshop.

Плановый рестарт как рабочий обходной путь

Раз рост потребления встроен в саму механику разведки карты и накопления объектов, а не является багом конкретно вашей сборки, практичный ответ — не дать памяти дорасти до OOM, перезапуская сервер по расписанию раньше, чем это случится само.

Общая схема на cron + systemd подробно разобрана в статье про автоматический рестарт по расписанию; для Zomboid она применяется без изменений, если у вас уже настроен systemd-юнит pzserver.service. Добавьте задачу в crontab пользователя pzuser:

crontab -e
0 5 * * * systemctl restart pzserver.service

Раз в сутки в наименее загруженное время сервера — для международной компании из разных часовых поясов идеального "тихого" окна может и не найтись, берите наименее загруженный слот по факту.

Перед остановкой важно дать серверу корректно сохраниться, а не убивать процесс kill -9 — это может повредить .db с прогрессом. systemctl stop отправляет сигналу штатное завершение, и сервер сам дописывает данные. Если нужно предупредить игроков заранее, добавьте в скрипт паузу перед остановкой и сообщение через RCON, если он у вас включён.

Плановый рестарт не устраняет причину роста — это управление симптомом. Но вместе с адекватным -Xmx и разумной Population он превращает непредсказуемые падения по OOM в контролируемый процесс, где сервер спокойно живёт сезонами без сюрпризов для компании.

Мониторинг памяти и выбор объёма RAM

Разовая проверка через htop — диагностика конкретного инцидента, для долгосрочной картины нужен постоянный мониторинг, который сигналит заранее, а не когда сервер уже упал. Минимальный вариант — скрипт с порогом, который проверяет RES процесса и шлёт уведомление при превышении:

#!/bin/bash
# pz-mem-check.sh
THRESHOLD_KB=7000000  # подстройте под свой -Xmx с запасом
mem=$(ps -o rss= -C ProjectZomboid64 | tr -d ' ')

if [ "$mem" -gt "$THRESHOLD_KB" ]; then
    curl -s -X POST -H 'Content-Type: application/json' \
    -d "{\"text\":\"⚠️ Zomboid сервер: память $((mem / 1024)) МБ, приближается к лимиту\"}" \
    "https://ваш-webhook-url"
fi

Добавьте в cron раз в 30-60 минут. Более системный разбор диагностики "сервер тормозит из-за памяти или из-за тиков" — в статье про мониторинг TPS и лагов на игровом сервере: там же о том, как отличить нехватку RAM от сетевых проблем у конкретного игрока.

При выборе объёма RAM закладывайте запас под естественный рост карты за недели игры, а не только под старт:

СценарийRAM машины на стартеРеалистичный запас через месяц
1-4 игрока, компактная карта6 ГБ6-8 ГБ обычно хватает
5-10 игроков, активная разведка8 ГБЛучше сразу закладывать 10-12 ГБ
10-16 игроков или большой модлист12+ ГБ16+ ГБ или разделение на несколько серверов

Это ориентировочные диапазоны, а не гарантия — сильно зависит от стиля игры компании и объёма модов. VPS с апгрейдом тарифа без пересоздания сервера снимает риск упереться в лимит посреди сезона.

Поднять сервер Project Zomboid за пару минут

Готовый образ MAATRIX GAMES: NVMe, AMD EPYC, DDoS-защита, панель управления. Локации UK, US, RU. Оплата картой РФ, СБП или криптой.

Создать сервер

Частые вопросы

Рост потребления памяти — это утечка в коде игры или нормальное поведение?

Это встроенная особенность механики: сервер держит в памяти подробное состояние всех разведанных клеток карты и накопленные объекты (трупы, предметы, разбитые машины). Это не классическая "забытая ссылка" в коде, а объективный рост объёма данных мира со временем.

Хватит ли просто увеличить -Xmx, чтобы проблема исчезла?

Нет, это отодвигает момент упора в лимит, но не останавливает сам рост — на большей куче сервер проживёт дольше без рестарта, но потребление продолжит расти тем же темпом. Без планового рестарта или снижения Population вы рано или поздно упрётесь и в увеличенный лимит.

MinutesPerPage правда не влияет на память сервера?

Не влияет — это исключительно скорость чтения книг навыков персонажем, к рантайм-памяти процесса отношения не имеет. Если ищете рычаг под память, смотрите на Population, RespawnHours и сам -Xmx.

Можно ли снизить память, не трогая -Xmx и не срезая популяцию зомби?

Частично да — уменьшение модлиста (особенно модов с большим количеством новых предметов и построек) и регулярная чистка заброшенных построек и трупов через админ-доступ снимают часть нагрузки, но без планового рестарта эффект временный.

Как часто перезапускать сервер, чтобы не упираться в память?

Единого числа нет — зависит от размера карты, модлиста и активности компании. Снимайте динамику через скрипт из статьи выше за пару недель и подбирайте частоту под свой реальный график роста, а не по чужой рекомендации с форума.