DevOps и аудит 22 апреля 2026 г.

Матрица 2026: параллельные воркеры iOS Simulator против компромиссов по памяти и дросселю на Mac mini M4 CI

NodeMac Team

Редакция mobile CI

Мобильным командам хочется, чтобы каждый Mac mini M4 «тянул все симуляторы сразу», но первый признак перегруза — не CPU: это сжатая память, зависшие запуски SpringBoard и нестабильные таймауты XCTest, которые исчезают, если уменьшить параллелизм на единицу. В этом материале — две матрицы (сколько воркеров на тир RAM, когда дросселировать, а когда шардировать), восемь шагов внедрения, которые можно приложить к тикету на изменение, и структурированные FAQ, чтобы операторы ссылались на ответы, а не перечитывали Slack.

Признаки того, что вы параллелите симуляторы вместо сокращения очередей

  • Флейки кучкуются ночью, когда ночные пайплайны накладывают четыре UI-сьюта на один хост, а на ноутбуках с двумя симуляторами всё зелёное.
  • Рост убийств SpringBoard или backboardd по ватчдогу, хотя xcodebuild местами всё ещё показывает успех.
  • Диск растёт ускоренно под ~/Library/Developer/CoreSimulator, а CPU ниже шестидесяти процентов — давление на память вынуждает подкачку и смену образов.

Если вы уже шардите бандлы по хостам, см. шардирование iOS UI-тестов на Mac mini M4 — там про горизонтальное разбиение работы; эта статья задаёт вертикальный потолок на каждой физической машине.

Практический смысл матрицы в том, чтобы заранее договориться о «красных линиях»: как только метрики пересекают порог, оркестратор не обсуждает «ещё один симулятор», а перекидывает нагрузку на другой SKU или увеличивает парк. Так CI перестаёт быть лотереей после каждого патча Xcode.

Матрица A — тир unified memory и безопасные параллельные дорожки симулятора

Допущения: рантаймы эпохи Xcode 16, Apple Silicon M4, UI-тесты со скриншотами. Уменьшайте значения, если на том же хосте без отдельного пула сборки ещё и компилируете.

RAM Параллельные UI-симуляторы (одна major ОС) Только unit-тесты, параллельные симуляторы Симптом «жёсткой остановки»
16 ГБ 1 (иногда 2 для крошечных сьютов) до 3 при строгом teardown циклы перезапуска SpringBoard > 2 в час
24 ГБ 2 UI-дорожки с лимитом скриншотов 4 с хуками выключения в простое сжатая память > 5 ГБ устойчиво
32 ГБ+ 3 UI-дорожки, если сборка изолирована 6 только с бюджетами RSS на джобу свободно на APFS < 45 ГБ во время сьюта

Матрица B — политика дросселя против каденции очистки (✓ / ✗)

Политика Помогает RAM Бьёт по throughput при перегибе Когда внедрять
Гасить симуляторы после каждой джобы Смешанные пулы без выделенных хостов под компиляцию
Переиспользовать загруженные симуляторы на весь пайплайн Выделенные хосты одной команды с ежедневными окнами purge
Раз в неделю стирать «недоступные» устройства Всегда; в паре с метриками хранения на диске

Почему подкачка прячется внутри CoreSimulator, а не в top

Монитор активности показывает десятки процессов со скромными следами, но стек симулятора резервирует крупные бэкинг-сторы под графику и файловые системы — пики приходятся на фазы установки приложения. Unified memory на Apple Silicon значит, что эти пики конкурируют с демонами компиляции и кэшами Swift. Практичное исправление — не крутить xcodebuild -parallel-testing-worker-number вверх, а выровнять ручку со строкой матрицы A под ваш SKU.

Удалённые парки Mac усиливают эффект: когда runner стоят в Гонконге, Японии, Корее, Сингапуре или США, разработчики списывают всё на задержку сети. Часто виноваты просто четыре симулятора на 16 ГБ в Токио — они ведут себя так же, как четыре симулятора в Вирджинии. География не создаёт гигабайты из воздуха.

Свяжите планирование параллелизма с размером пулов под SLO очередей, чтобы метки «ui-heavy» никогда не попадали на недобранный по RAM хост.

Если команда работает из разных регионов, полезно держать в runbook единый язык метрик: p95 длительности UI-джобы, размер каталога CoreSimulator, число бутов симулятора в час. Тогда сравнение площадок не превращается в спор «у нас в офисе быстрее».

Как метки оркестратора должны называть реальность

Дружелюбные ярлыки вроде macos-latest скрывают, шестнадцать гигабайт за очередью или тридцать два. Переименуйте пулы с указанием класса RAM и политики симулятора, например mac-m4-24g-ui-max2, чтобы продуктовые команды не ставили тяжёлые UI-сьюты на хосты, купленные под чистый compile-throughput.

Изменения меток сопровождайте дашбордом: число бутов симулятора в час. Если буты растут быстрее, чем мёржи pull request, вы трётесь о симуляторы, а не тестируете код — дросселируйте раньше, чем руководство спросит, почему mobile velocity «загадочно» рухнул после «безобидного» патча Xcode.

Числовые дефолты, которые стоит один раз записать в runbook

  1. Таймаут простоя: выключать симуляторы после 20 минут без трафика XCTest.
  2. Потолок ретраев: не больше 2 ретраев UI на pull request, чтобы не маскировать системное давление на память.
  3. Бюджет ватчдога: больше 0,5% падений SpringBoard на тысячу тестов считать жёстким сигналом к дросселю.

Золотое правило: не поднимайте число параллельных воркеров, пока еженедельный размер CoreSimulator не стабильно ниже вашего дискового порога и сжатая память не держится ровно на ночных прогонах.

Восемь шагов внедрения

  1. Замерить базу: параллельные воркеры, p95 длительности UI-джобы, размер каталога CoreSimulator.
  2. Промаркировать хосты по тиру RAM; запретить UI-heavy на 16 ГБ без явного исключения.
  3. Внедрить хуки выключения в teardown пайплайна, не только на успешных путях.
  4. Запланировать еженедельные erase с алертом, если длительность > десяти минут.
  5. Задокументировать откат: один флаг среды, который режет параллелизм пополам.
  6. Обучить mobile-инженеров: локальный ноут с восемью симуляторами не доказывает ёмкость CI.
  7. Согласовать политику скриншотов и видео-артефактов, чтобы диск не наполнялся за ночь.
  8. Масштабировать вширь дополнительными хостами NodeMac, когда дроссели честные, а очереди всё равно бьют SLO.

FAQ

Apple Silicon «просто тянет» больше симуляторов, чем Intel?

Производительность на ватт выше, но RAM конечна. M4 снимает оправдания про CPU, а не законы физики.

Должны ли симуляторы делить один том DerivedData?

Лучше изолированные корни DerivedData на джобу, чтобы снизить churn inode; общие кэши оставляйте только на compile-only хостах.

Где почитать гайд по SSH для runner?

Начните с справочного центра NodeMac про удалённый доступ, прежде чем тонко настраивать симуляторы по высоколатентным каналам.

Честный параллелизм симуляторов — это как раз зона, где Apple Silicon M4 с GPU и Neural Engine раскрывается: когда RAM перестаёт дёргаться, UI-тесты завершаются вместо «мистических» таймаутов. Нативный macOS, SSH для автоматизации и VNC, когда нужно увидеть зависший симулятор, повторяет то, что дизайнеры делают локально. Аренда выделенных Mac mini M4 по регионам изолирует UI-пулы от compile-пулов без закупки очередной партии ноутбуков, а предсказуемый объём RAM на хост бьёт просьбы «перезагрузите общий Jenkins Mac». Когда матрицы показывают, что нужен ещё один UI-only хост, откройте цены по регионам вместо того, чтобы наслаивать симуляторы до коллапса парка. Подключение по графической сессии описано в руководстве по VNC.

Поднимите UI-фермы Mac mini M4 с SSH/VNC и чистой гигиеной симуляторов

Выделенные узлы в HK·JP·KR·SG·US — разделяйте UI и compile-пулы предсказуемо.

NM
NodeMac Cloud Mac
Развёртывание ~5 мин

Выделенный Mac Apple Silicon в облаке. SSH/VNC, узлы HK·JP·KR·SG·US.

Начать