Server Debugger
El_NeumanМод для владельцев серверов. Отвечает на вопрос "почему мой сервер лагает" - и, если виноват какой-то мод, называет его по имени. Отдельный мод, ничего за собой не тянет. Ставится только на сервер, игрокам скачивать не нужно.
Писался в расчёте на то, что ты не программист. Команды ниже объяснены простыми словами: что делает, зачем, и что покажет.
Общая информация - что вообще происходит, когда "сервер лагает"
Сервер раз в доли секунды делает "тик" - обсчитывает мир: мобов, костры, температуру, всё сразу. Если один тик занимает не 0.05 секунды, а, скажем, 5 секунд - для игроков это фриз: мобы замирают, блоки не ставятся, всех "телепортит".
Причин у долгого тика немного, и они разные по лечению. Этот мод умеет отличать их друг от друга и показывать, какая именно у тебя.
Три вещи, которые надо знать, чтобы понимать вывод мода:
- Мусор и его уборка (GC). Игра и моды постоянно создают в памяти временные объекты. Когда их накапливается много, система устраивает "уборку мусора" (GC - garbage collection): замирает, проходит по всей памяти и выкидывает ненужное. Пока идёт уборка - сервер стоит. Обычно это доли секунды и незаметно. Но если памяти скопились гигабайты, одна уборка может занять секунды - вот и фриз.
- Утечка памяти. Уборка выкидывает только то, что больше никому не нужно. Если какой-то мод по ошибке продолжает "держать" уже мёртвых мобов (не отпускает ссылку на них) - уборка их выкинуть не может. Они копятся. Память растёт, уборки становятся всё длиннее, сервер лагает всё сильнее. Это и есть утечка.
- Горячий код. Иногда фриз не от памяти, а от того, что какой-то мод просто делает слишком много работы каждый тик (например, зря пересчитывает тысячи блоков). Память не растёт - код честно считает, но долго. Лечится не уборкой памяти, а поиском самого мода.
Чем Server Debugger отличается от MemLeakInspector?
MemLeakInspector - это специализированный инструмент для исследования памяти. Он показывает, какие объекты находятся в памяти, позволяет анализировать их состояние и сравнивать снимки памяти между собой. Однако он не определяет автоматически причину проблемы - интерпретировать результаты и искать виновника приходится самостоятельно.
Server Debugger - это комплексный инструмент диагностики сервера. Он анализирует зависания main-потока, лаги, паузы GC, проблемы с диском и утечки памяти. При обнаружении утечки он сразу пытается определить мод-виновник, что значительно ускоряет поиск проблемы. При этом он не предоставляет глубокий анализ объектов в памяти, временные снимки или подробный дашборд использования памяти.
Иными словами, Server Debugger отвечает на вопрос "какой мод вызывает проблему?", а MemLeakInspector - "какие объекты находятся в памяти и как меняются со временем". Эти инструменты не заменяют друг друга, а отлично работают вместе.
Что мод умеет, а что нет
Ловит уверенно и сам
- Утечки памяти. Когда какой-то мод по ошибке копит в памяти мёртвые энтити (мобов) и не отпускает - память растёт, сервер лагает всё сильнее. Мод находит это и называет виновника по имени (команда whodunit).
- Горячий код - какой мод. Если фриз от того, что мод долго считает каждый тик, команда ticks называет топ модов по нагрузке на сервер - без гадания и без ручной настройки. Раньше для этого нужно было вписывать подозреваемых вручную; теперь мод сужает круг сам.
- Кто спавнит сущности и что копится. Если растёт число мобов/снарядов, а leak упирается в "ваниль / движок" - команда spawns показывает, какой мод плодит сущности и что именно накапливается (спавнится быстрее, чем деспавнится). Это ловит случай, когда сущности не "утекли", а их просто слишком много спавнят.
- Понять, от чего вообще лаг. На каждый фриз мод говорит, куда ушло время: на уборку мусора, на слишком долгий код, или сервер просто ждал (диск, железо). Направление укажет всегда - не будешь гадать и копать не там.
- Кто вручную дёргает уборку мусора. Иногда мод сам приказывает "убрать мусор сейчас", и на большой памяти это фриз. Команда /sdebug gccallers показывает, какой мод это делает.
- Плохие настройки уборки мусора. Команда /sdebug env покажет, включён ли быстрый режим уборки, и если нет - это можно исправить (пример вывода и как чинить - ниже).
Помогает, но не назовёт виновника мгновенно
- Точные цифры по "тяжёлому коду". ticks сужает круг до 2-3 модов, но показывает частоту тиков, а не время. Мод может тикать часто, но быстро. Чтобы узнать, кто именно ест время, есть profile - он замеряет время по кускам кода, но смотрит только на моды, указанные в настройке. То есть: ticks назовёт подозреваемых сам, а profile подтвердит точными цифрами, если впишешь их в настройку.
Не умеет вообще
- Лаги из-за диска, сети или слабого железа хостинга. Мод скажет "причина не в коде модов" - но починить не сможет. Это к хостеру.
- Лаги у игрока (низкий FPS, дёргается картинка). Мод чисто серверный, клиент он не видит вообще.
- "Тяжело, но правильно". Если тех же тысяч блоков честно надо обсчитывать и в коде нет ошибки - мод покажет, что время уходит туда, но это уже не баг, а вопрос к тому, как мод устроен. Лечится не отладкой, а переделкой мода (или уменьшением нагрузки на сервере).
Одной фразой
Утечку памяти, горячий код и избыточный спавн - найдёт и назовёт мод сам. Всё остальное (диск, сеть, железо) - покажет верное направление, но дальше уже думать тебе.
Порядок действий - как дебажить по шагам
Команды вводятся в чат или консоль сервера, нужны права администратора. Не начинай с угадывания - иди по порядку, мод сам поведёт.
- Всегда начинай с /sdebug stalls - разбор последних фризов. Он сам напишет вердикт и укажет направление.
- Дальше смотри на вердикт:Вердикт "ПАУЗА GC" (память) -> /sdebug leak (есть ли утечка?), потом /sdebug whodunit (кто виноват?). Если whodunit упёрся в "ваниль / движок" - значит это не утечка, а избыточный спавн: включи /sdebug spawns on.
- Вердикт "горячий код" -> /sdebug ticks on, поиграй, потом /sdebug ticks (назовёт мод). Для точных цифр - profile + top.
- Вердикт "ожидание диска / lock" -> это железо/сеть хостинга, кодом не чинится.
- /sdebug env - общий осмотр в любой момент (в т.ч. проверить, включён ли быстрый режим уборки).
Всё пишется в файл Logs/serverdebugger-watchdog.txt - длинные отчёты смотри там. Трекеры (ticks on, spawns on) включай только когда дебажишь, потом off.
Команды
/sdebug stalls - разбор последних фризов (С НЕЁ НАЧИНАЮТ)
Когда вводить: первой, как только сервер лагает или лагал недавно. Это точка входа в любой разбор - она сама скажет, в какую сторону копать дальше. На свежезапущенном спокойном сервере покажет пусто (фризов ещё не было) - это нормально.
Мод ловит фризы сам и складывает их разбор. Эта команда показывает последние (по умолчанию 5). Каждый фриз - это блок, и последняя строка в нём - вердикт простым текстом, куда ушло время. Пример:
ServerDebugger: ЗАВИСАНИЕ Длительность : 5084 мс GC pause : 5008 мс (99%) ... ВЕРДИКТ : ПАУЗА GC. Сервер убирал мусор. Проверь на утечку: /sdebug leak
Или, если виноват не мусор, а код:
ВЕРДИКТ : ПРОЦЕСС РЕАЛЬНО СЧИТАЛ, GC ни при чём => горячий код.
Включите /sdebug ticks on, чтобы узнать какой.
- Важно и честно: stalls сам не назовёт конкретный мод. Он говорит только направление - "это уборка мусора" / "это код" / "это ожидание диска". Кто именно виноват, ищут следующие команды, каждая под своё направление. Куда идти после вердикта:вердикт "ПАУЗА GC" -> это память. Иди в блок "Про утечки" ниже (leak и whodunit), а заодно проверь gc.
- вердикт "горячий код" -> иди в ticks (назовёт мод сам), затем при желании profile / top для точных цифр.
- вердикт "ожидание диска / lock" -> это чаще всего железо хостинга, кодом не чинится.
/sdebug env - общее состояние сервера
Когда вводить: в любой момент, сразу после stalls для общего осмотра. Сервер должен просто работать, уборку запускать не нужно - команда читает текущее состояние.
Покажет блок вот такого вида (лишнее убрал):
ServerDebugger: окружение ProcessorCount : 24 Server GC : False <- вот эта строка важна Pause time % : 18.5 <- и эта Memory load : 6400 МБ / 16000 МБ
Что читать:
- Server GC - включён ли быстрый режим уборки мусора. False = медленный однопоточный, уборка тормозит сильнее, чем могла бы. Это "плохая настройка" сервера. Как исправить - в разделе "Ускорить уборку мусора" в самом конце. После починки строка станет True.
- Pause time % - какая доля времени уходит на уборку мусора. Единицы процентов - норма. 15% и выше (как 18.5 в примере) - уборка и есть твоя проблема.
- Memory load - сколько памяти занято. Близко к пределу - память может стать причиной сама.
Про утечки - две команды по порядку
Если stalls показал вердикт "ПАУЗА GC" - скорее всего это утечка. Ловится в два шага: сначала /sdebug leak проверяет, есть ли она вообще, потом /sdebug whodunit называет виновника. Идут именно в таком порядке.
/sdebug leak - ШАГ 1: есть ли утечка вообще?
Когда вводить: когда память сервера растёт со временем и лаги усиливаются - и обязательно дав серверу поработать (час-два после старта, или после игровой ночи, когда прошло много мобов). На только что запущенном сервере утечка ещё не накопилась, и тест покажет пусто.
Команда проводит уборку мусора вручную (сервер замрёт на пару секунд) и считает, сколько мёртвых мобов её пережили.
"Пережили" = должны были исчезнуть, но кто-то их держит, и уборка не смогла выкинуть. Логика простая: живых мобов уборка не трогает, а вот если давно исчезнувший моб "пережил" уборку - значит его незаконно держат, и это утечка.
Что покажет: процент выживших.
- Около нуля - утечки нет. На этом с утечками закончили, причину лагов ищи в другом (см. stalls, env).
- 80% и выше - утечка есть. Переходи к шагу 2 - /sdebug whodunit.
/sdebug whodunit - ШАГ 2: кто виноват в утечке?
Когда вводить: сразу после того, как /sdebug leak показал высокий процент (утечка подтверждена). Раньше смысла нет - если утечки нет, искать виновника незачем.
Эта команда делает так:
- Проводит уборку мусора вручную (сервер может замереть на несколько секунд).
- Находит всех мёртвых мобов, которых кто-то до сих пор держит.
- Прослеживает, кто именно их держит, и по какому моду проходит эта ссылка.
- Выдаёт список: какой мод сколько мёртвых объектов удерживает, с именем файла и места в коде.
Настраивать заранее ничего не надо. Результат выглядит так:
КТО ДЕРЖИТ УТЕЧКУ
прослежено 14203 объектов до держателя за 8 с
удержано объектов, по модам
14203 <- Rust and Rustbound Creatures
файл : RustboundCreatures.dll
тип : RustCreaturesReworked.BowtornTuning
поле : MoveSpeedBaselines
18 <- Другой мод
3 <- ваниль / движок
Первая строка - главный виновник. Дальше решаешь: удалить мод, обновить его, или написать автору о проблеме.
Важный случай: если whodunit показал держателем только "ваниль / движок", а не мод - это, скорее всего, не утечка. Сущности не "держатся" по ошибке, а просто спавнятся быстрее, чем деспавнятся. Для этого случая - команда spawns ниже.
/sdebug spawns - кто спавнит сущности и что копится
Когда вводить: когда растёт число сущностей (мобов, снарядов и т.п.) или есть подозрение, что кто-то плодит их без меры - а leak/whodunit при этом упираются в "ваниль / движок" и не называют мод. Так бывает, когда сущности не "утекли" (никто не держит ссылку), а просто спавнятся быстрее, чем деспавнятся. Это другой класс проблемы, для которого leak/whodunit по своей природе бессильны - и есть эта команда.
Порядок: /sdebug spawns on (включить), дай серверу поработать подольше - минимум час, лучше 2-3 (за 20 минут дисбаланс не проявится), потом /sdebug spawns (без слова - покажет отчёт). Выключить - /sdebug spawns off.
Показывает две таблицы. Пример:
ServerDebugger: спавн / деспавн сущностей
-_- накопление (спавн - деспавн за окно) -_-
спавн | деспавн | нетто | тип
1234 | 12 | +1222 | EntityDrifter
688 | 696 | -8 | EntityButterfly
(большое положительное 'нетто' = тип копится)
-_- кто спавнит (мод | тип : сколько) -_-
1234 ваниль / движок | EntityDrifter
48 Champion and Elite Mobs | EntityDrifter
Как читать: в первой таблице найди тип с большим +нетто - это то, что реально копится (спавнится куда больше, чем уходит). Во второй таблице найди этот же тип - левый столбец назовёт мод-источник (или "ваниль / движок", если плодит сам движок по условиям спавна).
А если у типа нетто около нуля или в минусе (как EntityButterfly в примере) - значит он не копится, уходит нормально, и подозрение с него снимается. Это тоже полезный ответ: например, если ты думал на дрифтеров, а трекер показал по ним минус - значит проблема не в них.
/sdebug ticks - кто грузит сервер тиками (для "горячего кода")
Когда вводить: когда stalls показал вердикт "горячий код" - то есть лаг не от уборки мусора, а от того, что какой-то мод долго считает каждый тик. Это более простой и автоматический способ, чем profile: не нужно заранее вписывать моды в настройку.
Порядок: /sdebug ticks on (включить), поиграй 10-15 минут, потом /sdebug ticks (без слова - покажет отчёт). Выключить - /sdebug ticks off.
Оборачивает тик-методы всех модов и считает, чей код на сервере вызывается чаще всего. Пример:
ServerDebugger: тики модов обёрнуто модов : 53 -_- как часто тикает каждый мод -_- 93205 (38%) Champion and Elite Mobs 62176 (26%) Overhaul lib legacy compat 51724 (21%) Rustbound Magic
Верхние строки - главные подозреваемые. Плюс, если трекер включён, строка "Main был внутри" в отчёте о зависании заполнится сама, назвав мод, чей тик висел в момент фриза.
Важно: частота тиков - это не время. Мод может тикать часто, но быстро. Трекер сужает круг подозреваемых до 2-3 модов; чтобы узнать, кто именно ест время, впиши верхний мод в WatchedModMarkers и запусти /sdebug profile on и /sdebug top для точных цифр.
/sdebug profile / top - точные цифры по "горячему коду"
Когда вводить: после ticks, когда уже знаешь подозреваемый мод и хочешь точные цифры по времени. В отличие от ticks (частота), profile замеряет именно затраченное время по кускам кода - но только у модов, указанных в настройке WatchedModMarkers.
Порядок: впиши подозреваемый мод (из ticks) в WatchedModMarkers, затем /sdebug profile on, поиграй, потом /sdebug top - покажет, какие методы съели больше всего времени.
/sdebug entities - сколько всего живых мобов в мире
Когда вводить: в любой момент, когда хочешь понять, реально ли мобов много в мире, или они только "висят" в памяти. Полезно рядом с /sdebug leak - вместе они отличают утечку от настоящего наплыва.
Показывает, сколько существ игра сама считает загруженными, с разбивкой по видам и по самым "населённым" участкам карты.
Зачем: отличить утечку от честного наплыва. Если команда показывает 80 000 мобов - они правда в мире, что-то сломало ограничение спавна. Если показывает 200, а /sdebug leak при этом находит тысячи "мёртвых" - значит мобы давно исчезли, но висят в памяти. Это утечка.
Прочее
- /sdebug gc - гистограмма причин уборок мусора (много Induced = какой-то мод дёргает уборку вручную).
- /sdebug gchook on + /sdebug gccallers - поймать, какой мод запускает уборку вручную.
- /sdebug findroot - ручной, более подробный вариант whodunit (полная цепочка ссылок). Нужен редко.
- /sdebug threshold [мс] - с какой длительности фриз попадает в лог (по умолчанию 500 мс = полсекунды).
- /sdebug lang [код] - язык вывода (см. ниже).
- /sdebug reset - очистить накопленную статистику (в памяти).
- /sdebug clearlog - очистить файл лога (начать с чистого листа).
Как читать блок "стойло" (зависание сервера) или же /sdebug stalls
Каждый такой блок - это один пойманный фриз. Ниже разобрана каждая строка на реальном примере.
стойло main-потока Время : 20:19:12.952 Длительность : 751.7 мс
Время - когда случился фриз. Длительность - сколько сервер стоял. 751.7 мс = 0.75 секунды сервер не отвечал. Обычный тик длится ~50 мс, так что это в 15 раз дольше нормы - игроки это почувствовали как заминку.
куда ушло время (дельты за окно стойла) GC pause : 697.6 мс (93%)
Самое важное, разберём подробно.
GC pause - это время, которое сервер простоял из-за уборки мусора (GC = garbage collector, сборщик мусора). Уборка - это когда система замирает, проходит по памяти и выкидывает ненужные объекты. Пока идёт уборка, сервер не тикает.
- 697.6 мс - сколько именно длилась уборка внутри этого фриза.
- (93%) - какую долю всего фриза она заняла.
Читается так: фриз был 751.7 мс, и из них 697.6 мс (93%) - это уборка мусора. То есть почти весь фриз - это уборка. Значит виновата именно она, а не что-то другое. Если бы тут стояло (5%) - уборка была бы ни при чём, копать надо было бы в другом месте.
CPU процесса : 187.5 мс (25%) <- СЧИТАЛ или ЖДАЛ: вот ответ
CPU процесса - сколько за время фриза сервер реально работал процессором (считал), а не просто стоял.
- 187.5 мс - столько сервер считал.
- (25%) - это 25% от длительности фриза.
Ключевая мысль: фриз длился 751 мс, а считал сервер всего 187 мс из них. Куда делись остальные 564 мс? Сервер их прождал, ничего не делая. Это отличает «сервер трудился» от "сервер завис в ожидании". Если бы тут было (95%) - сервер честно вкалывал. А (25%) значит - в основном ждал.
ThreadPool latency : 5.6 мс
Насколько задерживались фоновые задачи. Мелочь, важна редко. Большое число (секунды) означало бы, что фоновые потоки забиты - здесь всё в норме.
фон ЗА 9.3 с ДО стойла (вот настоящая нагрузка) Аллокации : 23.0 МБ/с CPU процесса : 20.6% от одного ядра
Это не про сам фриз, а про 9.3 секунды перед ним - чтобы понять, что творилось на сервере в спокойный момент до заминки.
- Аллокации 23.0 МБ/с - с какой скоростью код создавал в памяти новые временные объекты. Чем выше, тем чаще система вынуждена убирать мусор. 23 МБ/с - умеренно. Сотни МБ/с - это уже мод-мусорщик, который заваливает память и провоцирует частые уборки.
- CPU 20.6% от одного ядра - насколько сервер был занят перед фризом. 20% - расслаблен. Если бы тут было под 100% - значит сервер и так пыхтел, фриз был на пределе.
-_- память -_- Причина последней GC : gen0, AllocSmall, NonConcurrent (BLOCKING)
Почему запустилась уборка. Расшифровка технических слов:
- gen0 / gen1 / gen2 - "поколение", глубина уборки. gen0 - лёгкая, быстрая, только свежий мусор. gen2 - полная и тяжёлая, проходит всю память (именно она даёт длинные паузы). Здесь gen0 - самая лёгкая.
- AllocSmall - причина: "в памяти кончилось место под мелкие объекты". Это естественная уборка, память переполнилась сама. Противоположность - Induced, когда уборку запустил какой-то мод вручную (это уже повод искать виновника).
- BLOCKING - уборка была "останавливающей": сервер стоял, пока она шла. Бывает Background - фоновая, почти без остановки.
Сборки за окно : gen0 +1, gen1 +0, gen2 +0
Сколько уборок каждого уровня случилось за фриз. gen0 +1 - одна лёгкая уборка. Если бы тут было gen2 +1 - это была бы тяжёлая полная уборка, и паузу в сотни мс она объясняла бы полностью.
Аллоцировано в окне : 13 МБ (при замершем main это почти всегда ~0 — не показатель)
Сколько памяти создалось за время фриза. Обычно неинформативно (сервер же стоял), сам мод это и оговаривает - не обращай внимания.
Heap : 4027 МБ -> 4031 МБ
Heap - общий размер памяти под объекты (куча) до и после фриза. Здесь почти не изменился. Если бы после уборки куча заметно упала (например, 4027 > 2800) - уборка нашла много мусора и выкинула. Если не падает при большой куче - это признак утечки (мусор есть, но выкинуть нельзя, его кто-то держит).
Committed : 4226 МБ, фрагментировано 449 МБ (11% кучи)
- Committed - сколько памяти сервер зарезервировал у системы (обычно чуть больше heap).
- Фрагментировано 449 МБ (11%) - "дырявость" памяти. 11% - терпимо. 25%+ - уже мешает.
Working set / commit : 4396 МБ / 4509 МБ (в RAM 97%)
Сколько памяти сервера реально лежит в быстрой оперативке (RAM), а не уехало на медленный диск.
- в RAM 97% - почти вся память сервера в оперативке. Это хорошо.
- Если бы тут было, скажем, в RAM 60% - значит 40% памяти система выгрузила на диск (в pagefile), и уборка вынуждена поднимать её обратно с диска - медленно. Это признак нехватки оперативки на машине.
Page faults за окно : +1573
Сколько раз за фриз серверу пришлось лезть за памятью на диск, потому что её не оказалось в оперативке. Немного - норма. Тысячи-десятки тысяч - верный знак, что памяти на машине не хватает и она свопится на диск.
Memory load : 113274 МБ / 39060 МБ (порог 124992 МБ, свободно -)
Насколько забита память всей машины (не только твоего сервера - всей физической ноды у хостера).
- 113274 МБ - сколько занято на машине сейчас.
- порог 124992 МБ - красная черта, после которой система начинает паниковать и агрессивно убирать мусор.
- Если первое число подбирается к порогу - памяти на машине в обрез. Это часто не ты, а соседние серверы на той же железке.
код Main был внутри : Champion and Elite Mobs
Если включён трекер тиков (/sdebug ticks on) или профайлер, тут стоит имя мода, в тик-коде которого сервер застрял в момент фриза. Если оба выключены - будет "(включите /sdebug ticks on)", и информации нет, это нормально для обычного разбора.
ВЕРДИКТ : GC ЖДАЛ, а НЕ СЧИТАЛ: 187.5 мс CPU за 751.7 мс паузы.
Это hard page faults — куча выгружена в pagefile,
GC поднимает её с диска. Проблема в памяти МАШИНЫ.
Готовый вывод простым текстом. Мод сам собирает его из строк выше. Тут он говорит: уборка мусора шла 751 мс, но сервер за это время считал всего 187 мс - остальное ждал диск. Причина - памяти на машине не хватило, часть кучи уехала на диск, и уборка ползала, поднимая её обратно. Это железо хостинга, а не код мода.
Как читать вердикт в двух словах
Всё сводится к сравнению двух чисел: GC pause (сколько стоял из-за уборки) и CPU процесса (сколько при этом реально считал).
- GC pause большой + CPU почти равен ему > уборка честно работала. Лечится уменьшением кучи или ускорением уборки (Server GC).
- GC pause большой, а CPU маленький (как здесь: 697 мс паузы, 187 мс счёта) > уборка не считала, а ждала диск. Лечится добавлением памяти на машине - это к хостеру.
- GC pause ≈ 0, а CPU большой > уборка ни при чём, виноват тяжёлый код. Ищи мод через /sdebug ticks.
- Всё маленькое > сервер просто ждал (диск или блокировка).
Настройка мода
При первом запуске создаётся файл ModConfig/ServerDebuggerConfig.json:
{
"Language": "en",
"StallThresholdMs": 500,
"WatchedModMarkers": [ "xskills", "xlib", "xleveling", "xeffects" ]
}
- Language - язык вывода по умолчанию.
- StallThresholdMs - с какой длительности (в миллисекундах) фриз считается достойным записи в лог. 500 = полсекунды.
- WatchedModMarkers - подсказка для /sdebug profile и /sdebug findroot, на какие моды смотреть по умолчанию. Значения xskills, xlib и т.д. здесь - просто пример (мод изначально писался при отладке этих модов). Это не зависимость: сам ServerDebugger от xskills/xlib не зависит вообще и работает на любом сервере с любыми модами. Если хочешь - сотри их и впиши свои (например, тот, что назвал ticks), или оставь как есть. Главные команды (whodunit, leak, entities, stalls, gc, gccallers, env, ticks, spawns) этот список игнорируют и работают всегда. Обычному пользователю трогать не обязательно.
Язык
Сменить язык вывода на лету:
/sdebug lang ru
Выбор сохраняется. Без кода команда покажет текущий язык и список доступных.
Добавить свой язык: скопировать assets/serverdebugger/lang/en.json в файл со своим кодом (например aaa.json) и перевести значения. Плейсхолдеры {0}, {1} и команды /sdebug ... трогать нельзя - только текст вокруг. Файл подхватится сам. Если какой-то строки в твоём файле нет - подставится английская, так что переводить можно постепенно.
Технические слова (названия причин уборки вроде AllocSmall, имена мест в коде в выводе findroot) намеренно не переводятся - это идентификаторы, их нужно видеть как есть.
Ускорить уборку мусора (если env показал Server GC : False)
Это тот самый "как исправить", о котором сказано в описании /sdebug env. Если команда показала Server GC : False на мощном сервере - уборка мусора идёт в один поток, медленно, и паузы длиннее, чем могли бы быть. Лечится правкой одного файла настроек.
Что делать
- Через файловый менеджер хостинга найди файл VintagestoryServer.runtimeconfig.json (лежит рядом с самим сервером).
- Сначала сделай его копию - на случай, если что-то пойдёт не так, вернёшь как было.
- Открой файл. Внутри есть раздел configProperties. Допиши в него три строки (не забудь запятую в конце предыдущей строки):
"System.GC.Server": true, "System.GC.Concurrent": true, "System.GC.HeapCount": 6
Файл целиком будет выглядеть примерно так:
{
"runtimeOptions": {
"tfm": "net10.0",
"framework": {
"name": "Microsoft.NETCore.App",
"version": "10.0.0"
},
"configProperties": {
"System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false,
"System.Runtime.TieredPGO": true,
"System.GC.Server": true,
"System.GC.Concurrent": true,
"System.GC.HeapCount": 6
}
}
}
- Сохрани файл и сделай полный перезапуск сервера - не "reload", а именно рестарт. Настройка читается только при запуске, иначе не применится.
- Проверь: введи /sdebug env. Строка должна стать Server GC : True, а Pause time % - заметно упасть.
Что означают эти строки (простыми словами)
- Server GC - включает быструю уборку мусора в несколько потоков вместо одного. Это главное.
- Concurrent - часть уборки идёт в фоне, не останавливая сервер.
- HeapCount - на сколько ядер разложить уборку. Ставим 6: быстро, но не слишком жадно до памяти (без ограничения уборка заняла бы куда больше памяти).
Чего ожидать
На реальном сервере эта настройка снизила время в паузах с 28% до меньше 1%, а фризы от уборки мусора стали почти незаметными. Это не чинит утечки (утечку надо убирать отдельно, через whodunit), но делает любую уборку в разы быстрее.