
Комментарии 4
Приветствую коллега! С год назад, я с ноги вошел в конкурс Хабра "Код свободы", рассказав о том, как 15 лет разрабатывал и саппортил проект и, конечно, же не победил - первое место тогда получил уже модный вайб-кодинг уровня - "я за два дня сделаю больше чем вы за 15 лет". И честно сказать, уже и не надеялся встретить живого настоящего программиста на Хабре, а он - вот. Ну то есть Вы.
Я поддерживаю опенсорс в любом его проявлении и считаю ваш проект весьма интересным. Однако, мне не хватает хотя бы одного-двух сравнений со знакомой архитектурой. Я понимаю, что у вас проект вышел далеко за стадию прототипа и вероятно можете показать что-нибудь в сравнении.
Ещё мне понравилось, что пока, вы не позиционируете свой продукт как "убийцу линукс, макось или хотя бы виндовс".
А вдруг?)
Не станет ли ваш подход к распределению памяти проблемой для работы софта? Я никогда не занимался плотно низкоуровневым программированием и может быть вопрос не стоит внимания.
Приветствую, коллега! Спасибо! Очень приятно такое читать, особенно от человека, который сам много лет тащит один проект. По поводу сравнений - да, замечание справедливое. Я пока специально больше показывал GoOS изнутри, чтобы сначала объяснить, что именно там реализовано. Но сравнения с более знакомыми системами действительно нужны. Например, нынешний многопоточный аллокатор уже довольно естественно сравнивать с идеями mcache/mcentral в Go runtime, thread/per-CPU caches в TCMalloc и slab-подходом в Linux. При этом GC у меня пока заметно проще современного Go: stop-the-world, conservative и non-moving. Во второй части как раз про многопоточность, горутины, остановка нескольких потоков и то, во что всё это упёрлось на практике. Насчёт памяти - в перспективе это вполне может стать ограничением, если пытаться запускать в GoOS произвольный тяжёлый софт. Сейчас оно сделано намеренно жёстко и предсказуемо. Для нынешней архитектуры из небольших системных сервисов это скорее плюс, runaway-процесс не может незаметно сожрать всю машину. Но как универсальная модель для пользовательских приложений это, конечно, далеко не конечная точка. Если моя ОС дойдёт до серьёзных прикладных программ, придётся либо увеличивать профили и heap, либо делать его расширяемым несколькими резервами. Сам GC и slab/page-run allocator концептуально к 256 МиБ не привязаны, а вот текущие таблицы метаданных и индексация страниц рассчитаны именно на этот предел. До более трудных и серьёзных вещей я ещё дойду. Позже. А “убийцей Linux/macOS/Windows” я его и правда не вижу :) Мне сейчас гораздо интереснее довести отдельные механизмы до состояния, когда их уже можно честно сравнивать с взрослыми ОС
Да, это отлично увидеть сравнения. Может они уж есть во второй части, я ещё не читал. Ситуация с которой я периодически сталкиваюсь следующая (может вы сталкивались с ней в широкораспространенных ОС). Например в Linux - случай был в ред хате, в рамках безопасности всего, происходит что-то вроде инспекции соединений СУБД одним очень известным антивирусом. Таким образом выбирается абсолютно вся память и система останавливается. Ирония в том, что инспекцию соединений он тоже не может завершить, так как для завершения нужно ещё памяти. Учитывая работу на виртуализаторе, мы просто накидывали памяти, гасили антивирус и со временем, память высвобождалась. Аналогичное наблюдали и на windows, раздувается paged pool и всё. Тоже кстати, после работы того же самого известного антивируса. В отличие от Linux память не возвращалась, а просто была занята, до перезагрузки (которая и случилась ввиду невозможности работы).
Ваш подход он возможно не про это, но мне показалось, смерть системы в вашем случае будет просто быстрее происходить. Надеюсь, вам удастся провести нагрузочные тестирования с неожиданными ситуациями (например, отключилась планка памяти) и хотя бы кратко осветить в рамках цикла статей. Пойду читать вторую часть статьи.
У меня уже есть защита от бесконтрольного жора памяти процессом. Ядро учитывает выделенные физические страницы и ограничивает их число для каждого процесса (tiny — 8 МиБ, normal — 32 МиБ, large — 64 МиБ). Сюда относятся Го-куча, стеки, таблицы страниц и остальная физическая память адресного пространства. Резервирование виртуальных адресов эту квоту не расходует. Если при обращении к новой странице процесс исчерпал квоту или свободных физических страниц больше нет, ядро завершает его. Бесконечно ждать освобождения памяти он не будет. Когда GC освобождает страницы через VMDiscard, они возвращаются физическому аллокатору и перестают учитываться в квоте. Но с общим дефицитом памяти пока что всё проще, чем в зрелых ОС. Нет swap, фонового освобождения памяти по всей системе и OOM killer. Квоты ограничивают расход отдельных процессов, но суммарно им можно разрешить больше памяти, чем есть в машине. Поэтому одних квот недостаточно. Отключение работающей планки памяти вообще отдельный случай и в целом рассчитывать, что система не помрет после исчезновение используемой памяти, я бы сейчас не стал=) Тесты на общий дефицит памяти я себе записал. Достижение квоты отдельного процесса уже проверяется. Теперь нужно проверить, что будет, когда несколько процессов одновременно начнут выделять память и свободные страницы действительно закончатся
Память в GoOS, часть 1. От bump allocator к собственному heap и GC