WindowServer грузит процессор на Mac: что это за процесс и при чём аптайм

·

5 мин чтения

Циановый экран в простое, а под ним раскалённое амбер-ядро процесса, перегретое накопленным аптаймом
Паспорт генерации изображения

МодельQwen-Image 2512

КвантованиеQ6_K GGUF

Сид17

Шаги26

CFG2.5

Размер1360×768

Сэмплерeuler · simple

Время генерации19:11

Промт генерации изображения

Dark neon 'underside of progress' scene, cyberpunk workshop mood. A cold teal-cyan screen at idle, motionless, nothing happening; but beneath it, deep down, a warm amber process-core runs red-hot and hammers, overheated by accumulated uptime, fatigue from long unbroken running; cold static surface versus molten amber underside. Glowing heat-fractured metal, fine dust, heat shimmer, layered circuitry, fan hum. Deep shadow, volumetric haze, warm amber and cyan color palette, shallow depth of field, cinematic film still on 35mm, intricately detailed, ultra-detailed, fine textures, rich layered background, ornate mechanical detail, sharp focus, moody atmosphere.

И при чём тут аптайм машины.

Основной баг был побеждён. Цикл рендера виджета в Notification Center, который до этого выжигал ресурсы, наконец затих. Load average упал, система должна была вздохнуть спокойно. Но системный композитор WindowServer упрямо держал 40-60% одного ядра. При этом экран был статичен, курсор не двигался, машина визуально ничего не делала. Ядро молотило в пустоту, а батарея таяла с ощутимой скоростью.

Симптом был чистым, но виновник ускользал.

Охота на призраков в процессах

Первым делом пошёл стандартный перебор подозреваемых. В списке всегда есть «постоянные клиенты». Анимированные стикеры в мессенджере забирали около 32% - закрыл, нагрузка просела, но пол в 40% остался. Интернет-радио и coreaudiod работали в штатном режиме, без всплесков.

Затем внимание переключилось на браузер. Safari показал «горячую» вкладку с WebKit, которая потребляла около 20% CPU. Началась детальная зачистка: через AppleScript выгрузил список всех двадцати открытых вкладок, пытался через lsof вычислить, какой именно процесс сейчас «жрёт» ресурсы. И тут случилась странность: пока я искал хозяина, вкладка сама остыла до нуля. WindowServer при этом остался на своих 60%.

Проверил «эффект наблюдателя» - гипотезу о том, что сам открытый терминал с бегущими строками заставляет систему перерисовывать интерфейс. Для этого создал окно полной тишины на 20 секунд: свернул всё, замер. Результат - всё равно около 50%.

Второй монитор был физически отключен, динамические обои потребляли ничтожные 0.3%. Даже Stats.app, который в прошлых кейсах оказывался виновником, при выходе из приложения снизил общую нагрузку лишь с 50% до 40%.

Остался этот бетонный пол в 40%, который не объяснял ни один живой процесс.

Метод дельты в тишине

Я обратился к ИИ, чтобы выйти из круга «закрыл-проверил». Напарник заметил противоречие: WindowServer продолжает нагружать ядро даже тогда, когда все остальные потребители ресурсов обнулены. Это значило, что проблема не в том, что система рисует, а в том, как она это делает.

Выяснилось, что стандартный %CPU в top или ps - штука лживая. Он усредняет значения с уклоном в прошлое и часто маскирует реальную динамику системных демонов. Чтобы увидеть правду, нужно мерить не мгновенный процент, а дельту накопленного процессорного времени за фиксированный интервал абсолютной тишины.

Логика простая: берем общее время работы процесса, ждем, замеряем снова. Разница и будет честным потреблением.

WS=$(pgrep -x WindowServer | head -1)
t1=$(ps -o time= -p $WS | tr -d ' '); sleep 20
t2=$(ps -o time= -p $WS | tr -d ' ')

Замер до перезагрузки показал: WindowServer за 20 секунд тишины (без Stats.app) забирает ровно 40% ядра. При этом общее накопленное время процесса составило 12984:10. Это больше двухсот CPU-часов.

Прогноз вместо суеверия

WindowServer - это сердце графической сессии macOS. Его нельзя просто «прибить» через killall, не вылетев при этом из системы с потерей всех открытых окон. Точечная перезагрузка была невозможна, оставался только полный ребут.

Обычно совет «просто перезагрузись» воспринимается как капитуляция или техническое суеверие. Чтобы превратить это в диагноз, мы с ИИ сформулировали проверяемый прогноз.

Если виноват экстремальный аптайм и деградация процесса, то после ребута нагрузка в аналогичном окне тишины должна упасть до базовых 5-10%. Если останется в районе 40% - значит, мы всё ещё ищем внешнего виновника.

После перезагрузки замер за 12 секунд тишины выдал: 10.1%.

Гипотеза подтверждена цифрой. Процесс, который жил слишком долго, просто «засорился» или вошел в неэффективный режим работы с памятью и рендерингом.

Диагноз против ритуала

Эта история - зеркальное отражение моего прошлого разбора с Notification Center, но с важным отличием. Там виноват был конкретный виджет, который можно было вычленить и убить. Здесь мы столкнулись с износом самого фундамента - системного композитора.

Когда процент системного демона не объясняется ни одним пользовательским процессом, а сам демон является критическим и не подлежит точечному рестарту, единственным путем остается вычитание до дна.

Разница между «техническим шаманизмом» и отладкой заключается в прогнозе. Сказать «перезагрузись, должно пройти» - это гадание. Заявить «нагрузка упадет с 40% до 10%, потому что процесс накопил 200 часов CPU-времени» - это диагноз. Именно заранее определенное число превращает ребут из акта отчаяния в инструмент проверки.

Часть темы «Вторая жизнь железа» - там собраны остальные разборы про слабое и старое железо.

Как зашло?