Project Zomboid: память сервера переполняется
Сервер 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 и не срезая популяцию зомби?
Частично да — уменьшение модлиста (особенно модов с большим количеством новых предметов и построек) и регулярная чистка заброшенных построек и трупов через админ-доступ снимают часть нагрузки, но без планового рестарта эффект временный.
Как часто перезапускать сервер, чтобы не упираться в память?
Единого числа нет — зависит от размера карты, модлиста и активности компании. Снимайте динамику через скрипт из статьи выше за пару недель и подбирайте частоту под свой реальный график роста, а не по чужой рекомендации с форума.