Как линейное время превращается в Windows в O(n²)

Автор оригинала: Bruce Dawson
  • Перевод
image

Недавно я столкнулся с многоминутными задержками на моей рабочей станции. После расследования выяснилось, что причина проблемы заключалась в блокировке, которая могла длиться по пять минут, во время которых источник блокировки в основном крутился в цикле из девяти инструкций.

Для меня очень важно подбирать хорошие заголовки для своих постов, но я сразу же вспомнил, что подходящее название «48 ядер заблокированы девятью инструкциями» уже занято [перевод на Хабре] постом, написанным меньше месяца назад. Количество заблокированных процессоров отличается, а цикл немного длиннее, но на самом деле всё это заставляет испытывать дежавю. Поэтому пока я объясняю новую найденную проблему, мне был хотелось поразмыслить над тем, почему это случается постоянно.

Почему это происходит?


Грубо говоря, такие проблемы возникают вследствие наблюдения, которое я назову Первым законом Доусона о вычислениях: O(n2) — это магнит для алгоритмов, которые плохо масштабируются: они достаточно быстры, чтобы попасть в продакшен, но достаточно медленны, чтобы всё портить, когда туда попадут.


O(n2) в действии — данные взяты из моего случая

Что же происходит? Разработчик пишет код и использует алгоритм O(n2). Возможно, он этого не осознаёт, или алгоритм становится O(n2) из-за бага, или разработчик знает, что он O(n2), но думает, что это никогда не будет важным. В лабораторных условиях скорость кода приемлема, и приемлема она для большинства пользователей в реальном мире, но потом кто-нибудь создаёт 7 000 процессов со включенным App Verifier или создаёт двоичный файл с 180 000 элементов CFG, или собирает такую большую DLL, что при компоновке постоянно сканируется односвязный список, что забирает всё время процессора. При работе над временем запуска движка Source 2 компании Valve я обнаружил множество алгоритмов O(n2), каждый из которых прибавлял к времени запуска движка примерно по 30 секунд, то есть эта проблема возникает у очень разных разработчиков.

O(n2) — это магнит для алгоритмов, которые плохо масштабируются: они достаточно быстры, чтобы попасть в продакшен, но достаточно медленны, чтобы всё портить, когда туда попадут.

Именно.

Например, создание имён файлов лога App Verifier выполняется за линейное время для каждого запущенного процесса, и это нормально, пока ты не осознаешь, что это приводит к O(n2), если запущено множество процессов. Иногда даже неочевидно, что присутствуют вложенные циклы, или что формально это не O(n2), или неочевидно, что циклы могут выполняться так долго, что это может значительно влиять на скорость…

Так что учитывайте эту возможность, думайте о ней при написании кода, следите за тем, как масштабируется производительность при больших нагрузках и исследуйте подозрительные участки кода при профилировании таких больших нагрузок. Или оставьте это мне, чтобы я мог их искать и писать статьи в блог.

Вернёмся к нашим привычным жалобам


Как обычно, я занимался своими делами, работая на своей устаревшей, но всё ещё мощной рабочей станции с 48 логическими процессорами и 96 ГБ ОЗУ. Я ввёл ninja chrome, чтобы собрать Chromium, но… ничего не произошло. Я смотрел и ждал двадцать секунд, но сборка так и не начиналась. Поэтому я, разумеется, переключился на UIforETW, чтобы записать трассировку ETW. Точнее, попробовал это сделать. Попытавшись начать запись трассировки, UIforETW завис. Впервые в моей практике баг использовал меры защиты, чтобы помешать мне его исследовать!

Через одну-две минуты началась сборка Chromium, а UIforETW запустил трассировку, но она началась слишком поздно и у меня не было ни малейших сведений о том, что произошло.


Параметры UIforETW с выбранным Circular Buffer Tracing

Когда спустя пару дней произошло то же самое, UIforETW снова не смог ничего сделать. На этот раз я оставил трассировку работать в кольцевых буферах памяти, чтобы быть готовым к тому, что зависание произойдёт в третий раз. Однако это сильно снизило скорость работы моих инструментов сборки, поэтому спустя несколько часов я сдался.

Потом эта ситуация повторилась снова. На этот раз я запустил инструмент записи трассировок ETW, созданный Microsoft — wprui, и мне удалось начать запись. Примерно 40 секунд спустя сборка начала работать и я получил трассировку!

Теперь можно приступать к расследованию?


Ранее я заметил в «Диспетчере задач», что во время этих зависаний выполнялся WinMgmt.exe. Взглянув на данные CPU Usage (Precise) в WPA, я убедился, что по прошествии более сорока секунд, на протяжении которых почти единственным работающим процессом был WinMgmt.exe, моя машина оживала после того, как WinMgmt.exe завершал работу:


Ожидаем пробуждения процессов после завершения WinMgmt.exe

Всё это довольно подозрительно, но мои мудрые читатели знают, что «после» — не значит «вследствие», и потребуют доказательств.

Как и в прошлый раз, я приблизил на графике момент разблокировки, отсортировав переключения контекста по Switch-In Time и поискав первое переключение с долгим значением Time Since Last (обозначающим длительность времени, в течение которого поток не выполнялся). Пропустив с десяток потоков, которые были просто короткими простоями, я нашёл первый из множества, который ждал 41,57 секунд. Спящий поток не пробуждался WinMgmt.exe, но я быстро выяснил, что он пробуждался потоком, который пробуждался WinMgmt.exe за доли миллисекунды до этого.

Объяснения графиков CPU Usage (Precise) и концепций readying-thread/new-thread см. в этом туториале или в этой документации.

На скриншоте с данными переключения контента в строке 17 находится поток 72,748(WinMgmt.exe), активизирующий поток 74,156 (svchost.exe). Далее в строке 19 поток 74,156 (svchost.exe) активизирует поток 58,704 (svchost.exe), который ожидал в течение 41,57 секунд. Это первый поток, пробуждающийся после долгого сна и с этого продолжается цепочка активизации потоков. Только что активизированные потоки можно увидеть в столбце New Thread Id, а затем спуститься на несколько строк вниз и увидеть их в столбце Readying Thread Id, активизирующими другой поток. Названия и ID процессов помогают разобраться с контекстом. Строка 17 связана со строками 18 и 19, строка 19 связана с 20, которая связана со строкой 23, которая связана со строкой 27, и так далее; каждый поток активизируется предыдущим в цепочке потоком:


Чудовище пробуждается — долго простаивавшие потоки оживают

41,57 — это большое для блокировки потока время, но на самом деле блокировались сотни потоков, и заблокированы они были намного дольше. Единственная причина, по которой их значение Time Since Last примерно равно 41,5 секунды, заключается в том, что это длительность трассировки до того, как зависание не разрешится.

Похоже, результаты согласуются с теорией, что проблема заключается в WinMgmt.exe, но не доказывают этого. Моя уверенность возросла, когда я взглянул на svchost.exe (3024) в Trace-> System Configuration-> Services и выяснил, что он является службой Winmgmt, но мне по-прежнему нужна была бОльшая определённость.

Покопавшись ещё немного (побродив вперёд и назад по времени), я решил, что взаимодействия слишком сложны, чтобы анализировать их подробно, особенно без имён потоков, которые могли бы намекнуть нам, чем занимаются 25 разных потоков в svchost.exe (3024).

Доказательство!


Тогда я решил подойти к доказательству вины WinMgmt.exe иначе. Возможно, с этого и стоило начать, но это было бы слишком просто. Я взял командную строку WinMgmt.exe из таблицы Processes в WPA и запустил её вручную. Команда имеет вид:

winmgmt.exe /verifyrepository

и её выполнение заняло около пяти минут. Пока она работала (и у меня было много времени), я выяснил, что не могу запустить трассировку ETW из UIforETW. Такое доказательство было лучше, чем любой запутанный анализ, который я мог провести.


Конфигурация для отображения только давно дремлющих потоков

Затем я снова выполнил repro с уже запущенной трассировкой; проанализировав трассировку, я обнаружил более сотни процессов, потоки которых были заблокированы более пяти минут!

И снова за дело…


По привычке я снова посмотрел на данные CPU Usage (Sampled), чтобы увидеть, на что WinMgmt.exe тратит время. Я быстро выяснил, что 96,5% сэмплов происходило в repdrvfs.dll!CPageCache::Read(), вызываемой в четырёх разных стеках:


Четыре пути, которые привели меня к CPageCache::Read

Дерево полных стеков к этой функции показаны здесь, в основном для людей из Microsoft, которые захотят исследовать эту проблему:


Полные стеки, ведущие к CPageCache::Read по трём путям

Я добавил столбец адреса и выяснил, что 95,3% сэмплов приходилось на один цикл из девяти инструкций (сэмплы всегда попадали только на семь из девяти инструкций (если хотите узнать, почему, то см. здесь), но отладчик показывал полный размер цикла):


Сэмплы по адресу — семь очень «горячих» адресов

Затем я запустил winmgmt.exe /verifyrepository вручную, и параллельно собирал данные счётчика ЦП о выполняемых инструкциях ветвления. Из этого я примерно мог прикинуть, сколько раз выполнялся цикл. Вероятно, это было необязательно, но я хотел убедиться, что цикл выполнялся много раз, а не выполнялся медленно (по какой-то причине). Я подумал, что очень круто, что я могу сделать это просто, достаточно внести крошечное изменение в пакетный файл. Я выяснил, что WinMgmt.exe выполнял приблизительно по одной инструкции ветвления на цикл, то есть цикл (который, как я уже знал, потреблял бОльшую часть времени ЦП) выполнялся чрезвычайно быстро, а замедление возникало из-за того, что он прогонялся сотни миллионов раз.

Задержка Xperf


Просто ради дотошности я решил посмотреть, почему UIforETW не мог запускать трассировку во время этого инцидента. Выяснилось, что UIforETW запускал xperf, но xperf простаивал 41,5 секунд (на самом деле больше) в этом стеке вызовов:

xperf.exe!wmain
xperf.exe!CStopTrace::Execute
perfctrl.dll!LoggingSession::EnumLoggers
perfctrl.dll!LoggingSession::LoggingSession
perfctrl.dll!LoggingSession::CreateProviderList
perfctrl.dll!GetProviderInfoCache
perfctrl.dll!CProviderInfoCache::CProviderInfoCache
tdh.dll!TdhfEnumerateProviders
tdh.dll!TdhpWbemConnect
wbemprox.dll!CLocator::ConnectServer
wbemprox.dll!CDCOMTrans::DoActualConnection

Если вкратце, то xperf вызывается Wbem, а потому блокируется этой проблемой. xperf пытается остановить трассировку, прежде чем начнёт её, потому что я добавил такое поведение, чтобы сделать запуск трассировки более отказоустойчивым. Подозреваю, что зависание всё равно происходило бы, но точно этого не знаю.

Создаём графики вычислительной сложности


Я заметил, что WinMgmt.exe сканирует каталог c:\windows\System32\wbem\Repository, который на моей машине занимает 1,9 ГБ, поэтому попросил на работе и в Twitter сообщить, какой объём занимает этот каталог, чтобы получить точки данных. Также я попросил людей зафиксировать время выполнения winmgmt.exe /verifyrepository и начал составлять график. Даже несмотря на то, что эти тесты проводились на совершенно различных машинах с разными скоростями ЦП, график получился довольно чётким:


Отношение между квадратным корнем от времени и размером репозитория

Этот график отношения sqrt(time) к размеру репозитория неправдоподобно идеален для данных, полученных с шести разных машин, и тем не менее, он реальный. Очевидно функция VerifyRepository имеет производительность O(n2). Если n — размер каталога Repository в ГБ, тогда VerifyRepository занимает примерно 1.6*n2 минут. Это хорошая примерная оценка для всех значений — от доли секунды до десяти минут.

Значимость


Или мне везёт, или я просто наблюдательный, потому что за пару недель никто больше не сталкивался с этой проблемой — я думал, что странности творятся с моей машиной. Но внезапно я начал слышать подозрительно похожие жалобы от коллег. У одного из них был репозиторий на 2,6 ГБ, проверка которого занимала десять минут. Проблема повлияла на некоторых наших CI-разработчиков, и в разной степени — на разных других людей. Мои коллеги обычно знают, что в случае проблем с производительностью машин под Windows нужно сказать об этом мне, однако, вероятно, есть множество других сотрудников Google, работающих под Windows, которым мешает этот баг, но они этого не осознают.

К счастью, я уже начал работать с нашим ИТ-отделом. Я нашёл скрипт, запускавший WinMgmt, и узнал, что он выполняется ежечасно. Это означало, что моя машина выполняла WinMgmt.exe /verifyrepository 10% времени, а у некоторых из моих коллег — больше 16% времени. Существует довольно большая вероятность получить задержку в десять минут перед сборкой.

К моменту, когда начали поступать отчёты, исправление уже было на пути в продакшен. Скрипт был необязательным, и уж точно не стоил вызываемых им проблем, поэтому исправление заключалось в отключении его вызова.

Итоги


winmgmt.exe /verifyrepository содержит цикл из девяти инструкций, количество итераций выполнения которого пропорционально квадрату размера репозитория wbem. Из-за этого выполнение команды может занимать до десяти минут, хотя на самом деле она должна выполняться всего за несколько секунд. Это плохо само по себе.

Но ещё хуже то, что во время своей работы команда выполняет блокировку WMI (Windows Management Instrumentation), поэтому любой процесс, выполняющий операции WMI, зависнет.

Удивительные загадки


Скрипт, выполнявший каждый час winmgmt.exe /verifyrepository, занимался этим многие годы, но проблемное поведение начало проявляться всего один-два месяца назад. Предположительно, это означает, что репозиторий wbem недавно стал становиться намного больше. Задержки при 0,5 ГБ легко не заметить, но от 1,0 ГБ и выше они могут уже напрягать. По предложению в Twitter я запустил strings.exe для файла objects.data. Многие из самых часто встречающихся строк содержат в названии «polmkr», но я не знаю, что это значит.

Я опубликовал отчёт о баге в Twitter, и поначалу он вызвал какое-то движение у команды WMI, но потом я перестал получать ответы, поэтому не знаю, какова ситуация сейчас.

Я бы хотел увидеть фикс проблемы с производительностью, и мне бы хотелось, чтобы наш ИТ-отдел смог найти и устранить проблему, из-за которой наши репозитории wbem становятся такими большими. Но пока ИТ-отдел пообещал не запускать больше каждый час команду /verifyrepository, что должно позволить избежать нам проявления наихудших симптомов.

Ссылки


  • Общий список туториалов, расследований и документации ETW выложен здесь: https://tinyurl.com/etwcentral
  • Туториал по CPU Usage (Sampled) (для поиска того, на что тратится время ЦП) находится здесь, а документация — здесь
  • Туториал по CPU Usage (Precise) (для нахождения причин того, почему не могут выполняться потоки) находится здесь, а документация — здесь
  • Ссылки на отдельные статьи приведены в теле поста, так же можно найти их в моей категории Investigate Reporting
  • Другие байки об алгоритмах O(n2) можно почитать на Accidentally Quadratic

Обсуждение статьи на Reddit находится здесь, обсуждение на hacker news — здесь, тред в Twitter — здесь и, возможно, здесь
Поддержать автора
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 53

    +10

    Я сначала думал, что за дежа вю такое, потом понял, что это был другой, но похожий пост того же автора (и переводчика :D).

      +4
      T=1.6*n^2 * [мин/Гб^2]

      Решение же очевидно — очистить этот репозиторий нахрен n->min.

      winmgmt /salvagerepository
      winmgmt /resetrepository
        +1
        Ну да — чуть что — переустанавливай Windows.
        –9
        Как линейное время превращается в Windows в O(n²)

        Никак. Линейное время всегда O(n^2).
          +12
          O(n) смотрит на эту реплику с недоумением.
            –9
            Нет, O(n) смотрит на эту реплику и соглашается с ней.
            +1
            Не могу понять, толлинг ли это, или вы серьезно. Но на всякий случай, вот вам википедия и
            скриншотик с нее


              +7
              Вы оба правы — линейная время это время O(n), но ведь любая функция из класса O(n) также входит в класс O(n^2) и например O(2^n). Просто само обозначение O(...) — это верхняя граница.
              Более формально правильным названием статьи было бы «Как линейное время превращается в Ω(n^2)», т.к. Ω — это наоборот, нижняя граница. Другое дело, что на практике часто всё-таки на такие различия между обозначениями внимания не обращают.
                –1
                Вроде для этого есть o(n^2), что по хорошему и нужно было использовать в этой статье, но видимо на матчасть редко обращают внимание судя по минусам у поста.
                  0
                  Спасибо за пояснение.
                  Различия между обозначениями в нотации bigO хорошо описаны например в Кормане
                  +1
                  Я думаю, что он имеет ввиду то, что с формальной точки зрения все, что принадлежит O(n), так же принадлежит O(n^2). Другое дело, что если мы знаем, что алгоритм линейный, то мы опишем его как O(n), а не O(n^2), т.к. это более содержательное описание.
                    0

                    Если мы это правда знаем, то лучше описать его как Θ(n).

                    0
                    Какое утверждение вы пытаетесь сделать и как оно следует из приведённой статьи?
                      0
                      Какое утверждение вы пытаетесь сделать

                      Тот же вопрос хочется задать и вам. Если вы хотели сообщить, что знаете о существовании не только «O» большого, но и о других обозначениях асимптотики, то так и надо было говорить. Но это необязательно, ибо статья не замахивается на роль труда по теории алгоритмов, а в жизни все используют «О» большое для примерного обозначения сложности и не заморачиваются.
                        –3
                        Тот же вопрос хочется задать и вам.

                        Я не спрашивал вас о том, чего вам хочется. Если вам непонятен смысл моего вопроса, попробуйте прочесть его повторно проверяя непонятные вам слова в толковом словаре.
                          0
                          Друг, вот зря ты тратишь свою возможность комментирования раз в час на такие бессмысленные пассивно-агрессивные высказывания. Так и до комментария раз в день недолго.
                          А вопросы надо задать в той форме, чтобы на них было, что ответить.
                            –4
                            Мужик, ты мне не друг и твоё мнение о моих возможностях меня не интересует. А на вопрос надо ответить ровно то, что ты пытался донести приводя ссылки на википедию и подчёркивая красным в скриншотике. Ибо на данный момент кроме определений терминов твой комментарий ничего не доводит; к тому комментарию, на который ты ответил, ничего не добавляет, не противоречит и не соглашается. Т.е. твой комментарий попросту не имеет смысла в контексте обсуждения. И как я понимаю, смысл уже не появится.
                              +1
                              Окей, недруг, пытаюсь объяснить ещё раз. Ты своим комментарием, очевидно, пытаешься показать, что знаешь академическое определение «О» большого. Это круто, конечно. Но статья явно не замахивалась на академический труд. Позволю процитировать комментарий netch80 о практическом использовании нотации «О» большого:

                              > Практический же — что не просто выполняется неравенство, но и нет более адекватной оценки, то есть если пишут O(n^2), то O(n log n), O(n) и т.п. не подходят.

                              Твое указание на то, что O(n^2) в академическом понимании включает в себя в том числе линейную сложность, кстати, также абсолютно ничего не добавляет полезного к статье. Ибо все поняли, что O(n^2) в данном контексте указывает на сложность квадратическую.
                                –1
                                Ты своим комментарием, очевидно, пытаешься показать, что знаешь академическое определение «О» большого.

                                Ложь. Можешь в качестве доказательства привести скриншотик моего комментария, не забыв подчеркнуть красным те слова, которые по твоему мнению пытаются это показать. Ну или можешь прочесть комментарий и попробовать понять его, в конце-концов.

                                если пишут O(n^2), то O(n log n), O(n) и т.п. не подходят.

                                Не «не подходят», а «неизвестно». Для того, чтобы показать, что они не подходят, есть нотация Ω(n).

                                Твое указание на то, что O(n^2) в академическом понимании включает в себя в том числе линейную сложность, кстати, также абсолютно ничего не добавляет полезного к статье.

                                Опять ты читаешь мой комментарий и не понимаешь смысл. Я не указываю на то, о чём ты пишешь. Я указываю на допущенную автором при использовании формальной нотации ошибку.

                                Когда ты беседуешь в курилке с мужиками, говори как угодно — хоть просто «эн квадрат». Когда ты пишешь статью на более-менее серьёзном ресурсе — используй нотацию правильно. Или ты назовёшь системный блок процессором в своей статье? Тоже ведь будет всем понятно что ты имел в виду, да? Однако некорректное использование терминологии кое-что скажет твоим читателям о тебе. Если конкретно для тебя это неважно — это не значит что мой комментарий не имеет смысла.
                      0
                      Есть таки два понимания знака O(), формальный и практический. Формальный — что f(x) = O(g(x)) означает, что f(x) <= C*g(x), тогда линейное C*n безусловно O(n^2). Практический же — что не просто выполняется неравенство, но и нет более адекватной оценки, то есть если пишут O(n^2), то O(n log n), O(n) и т.п. не подходят.

                      Мне этот практический подход больше импонирует потому, что даёт оценку полезности лучше, чем формальный :) Иногда нельзя по этому принципу сравнить два подхода, или две оценки, но это таки редко.

                      К сожалению, другие обозначения из этой серии не дают нужного. Θ — не учитывает случаи, когда в результате счастливого попадания в «мягкий» вариант затраты оказались меньше. Например, пусть мы знаем, что ни один элемент не отстоит больше чем на 10 позиций от своей позиции после сортировки; тогда пузырёк и вставки будут O(n), но это 10 будет заложено в C. Ω — ещё хуже — жёсткая нижняя оценка или не подходит вообще, или не имеет смысла.

                      Так что приходиться довольствоваться «внешним» по отношению к самому знаку пониманием «нет более сильной оценки» или «оценка достаточно сильна для наших целей».
                        0
                        Формальный — что f(x) = O(g(x)) означает, что f(x) <= C*g(x)

                        Не совсем, там предел при x к бесконечности.


                        Вопрос амортизированных/лучших/худших случаев уже куда интереснее, да.

                          0
                          > Не совсем, там предел при x к бесконечности.

                          Не предел, а при x больше некоторого (если рассматриваем стремление к бесконечности, как нужно для алгоритмов в CS) или ближе некоторого ε (как в математике). Это условие я пропустил как наверняка очевидное участникам дискуссии.

                          > Вопрос амортизированных/лучших/худших случаев уже куда интереснее, да.

                          Угу. Тут поэтому давно назрело как-то уточнить символы, пока же используются словесные добавления.
                          Как злобный пример — стоимость вставки в хэш-таблицу классической закрытой адресации. Формально O(1), но амортизированное O(1). GCC STL, Java и прочие — что, таки писать, что O(n)? Так неэффективно для (n-1)/n (условно) случаев, когда ресайзинга нет. O(1)? Неверно для случая ресайзинга.
                          Остаётся писать: Θ(1) без ресайзинга и Θ(n) с оным. Мне эти муки выбора напомнили анекдот про Хрущёва среди свиней…
                          (Disclaimer: переполнение одной корзины в хэш-таблице не учитываем, а то и в этом случае Θ(n) получится. А счастье было так близко.)
                            0
                            Не предел, а при x больше некоторого (если рассматриваем стремление к бесконечности, как нужно для алгоритмов в CS)

                            Так это и есть определение предела (вернее, его кусок) при x, стремящемся к бесконечности.


                            Как злобный пример — стоимость вставки в хэш-таблицу классической закрытой адресации.

                            Мне тут больше нравятся всякие ФП-структуры данных и их амортизированный анализ, со всякими методами физика и методами банкира. Можно интересно побеседовать.

                              0

                              Предела может не существовать, но "О большому" это не помешает. К примеру, можно написать что sin n = O(1)

                                –1

                                Да, потому что там верхний предел.

                      0

                      Интересно, опишите тогда квадратичное время

                        0
                        Согласно «скриншотику с википедии» квадратичное время — это O(n^2). Т.е. это любая функция от n, для которой можно указать такую константу C, что начиная с некоторого n_0 значение функции не будет превышать C n^2.
                      –8
                      А мужик крут, потратил столько времени на поиск баги в Windows, написал об этом статью. А проблема в своём репозитории… Да кому она интересна?
                        +1

                        Если в рабочее время, так это может быть куда интереснее обычной работы. Только вот коллег отвлекает...

                          +4
                          Не в своём. Этот репозиторий — часть WMI — подсистемы Windows. Вот кусочек из документации, касающейся указанной в статье команды:
                          /verifyrepository
                          Performs a consistency check on the WMI repository. When you add the /verifyrepository switch without the argument, then the live repository currently used by WMI is verified.
                          0
                          Ну вот у меня размер этого каталога — 58 мегабайт. «Как им удается» (с)
                            +3

                            Я думаю вы недостаточно часто пересобираете хром из сорцов

                              0
                              Ну так-то да, но если я ничего не перепутал, это может влиять, только если при каждой компиляции добавляют классы в WMI. Это, конечно, возможно, но как-то необычно.
                                0
                                Да, что-они там химичат сами в гугле. У меня корпоративаня машина со всеми вытекающими. Вин10 стоит с самого релиза. При этом размер папки 120МБ
                            +4
                            В последнее время замечаю, что десятка начинает тупить. Тупит просто всё — даже курсор мышки передвигается рывками. В диспетчере задач всё глухо — загрузка минимальная. При этом железо достаточно свежее — шестиядерный i5-8400, 32 Gb RAM. Закрываю браузер, стопаю машины на локальном Hyper-V — лучше не становится. После перезагрузки всё опять нормально.
                            Антивирусами проверял — тишина. В следующий раз попробую провести расследование по описанной схеме.
                              0
                              если курсор мыши в винде передвигается рывками, надо начинать думать на железо
                              для начала журнал событий посмотреть, у меня в таких случаях обычно была проблема с дисками.
                                0
                                Это просто windows вам так намекает, что пора обновлять железо.
                                  0
                                  Мышь беспроводная?
                                    0
                                    Нет, дело точно не в мыши (да и проводная она). Я ведь тоже не первый день с компьютерами. Тормоза точно на уровне винды — рывки курсора — это только одно из проявление. Помимо этого есть задержки на открытии меню «пуск», диспетчера задач и т.д.
                                    Машина рабочая, перегружается редко, описанное поведение наблюдается 1-2 раза в неделю и ничем не лечится до перезагрузки. Последние 3 дня, например, всё в порядке.
                                    Больше всего удивляет тишина в диспетчере задач — загрузка процессора — единицы процентов, а всё тормозит. Загрузку дисков тоже смотрел и расследовал — не нашёл ничего заслуживающего внимания.
                                      +1
                                      Температуру моста проверьте.
                                        +1
                                        Ровно те же симптомы были. Запустил я (уже после перезагрузки) rammap, а там в выделенных кусочках памяти
                                        вот такая прелесссть:
                                        image

                                        Что-то мне это так не понравилось — кому понравятся оставшиеся куски памяти от сотен тысяч процессов одного и того же модуля — пошел гуглить имя процесса, смутно ощущая, что я про что-то вот прям похожее читал на хабре. И точно!

                                        Именно та же картина: за три дня после перезагрузки счетчик хендлов (смотрел в sysinternals process manager) уехал за 300000. Приложение прибил, количество хэндлов в системе за несколько секунд упало до 167000.

                                        В сервисах нашел эту дрянь, но gui изменить тип запуска не дает, так что изменил в реестре (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SynTPEnhService) значение Start с 2 (авто) на 4 (запрет).

                                        Через несколько месяцев, правда, оно вернулось. Просто повторил, пока полет нормальный.
                                          0
                                          вот такая прелесссть:

                                          Такое ощущение, что у вас ClearType и альтернативный порядок субпикселей. Читать скриншот практически невозможно.
                                            –1
                                            Ощущение аналогичное. Но это не у меня. Откройте эту же картинку в полном размере: habrastorage.org/webt/sd/-7/ea/sd-7ea3jnhjbxi8f2udvrr7hxww.png и убедитесь в этом.
                                              0
                                              У меня кастомный стиль и картинка и так была в полном размере. Монитор случайно на бок не повёрнут?
                                      +1

                                      О, долго мучился с такой-же проблемой. Даже систему переустанавливал и начал уже грешить на железо, как тут выше многие советуют. Но смущало все же то, что во-первых в журнале событий все чинно, а во-вторых, ubuntu на той-же машине работала без нареканий (на подвисания во всяком случае).
                                      Собственно, эта статья и вдохновила разобраться таки в причинах этого безобразия с помощью ETW/xperf.
                                      В общем, в моем случае тригерром подвисаний стала комбинация из нескольких вещей:


                                      1. При смене темы оформления в процессе explorer-а лочится UI поток.
                                      2. Смена цвета акцента означает смену темы оформления
                                      3. В настройках персонализации стояла галочка automatically pick an accent color from my background
                                      4. Там же в качестве фона было выбрано слайд-шоу со сменой картинки каждую минуту.

                                      Собственно, дальше уже наверное понятно, что происходило. Каждую минуту смена фона раб. стола запускала цепочку "смена фона -> смена цвета акцента -> смена темы -> блокировка UI потока эксплорера -> фризы и подвисания всего UI".


                                      Я конечно допускаю, что первоисточник проблемы может быть и не в этом, а где-то глубже. Ибо после перезагрузки подвисало намного меньше, чем после десятков часов работы, и на чистой системе до установки всего софта тоже сильных подвисаний вроде бы замечено не было. Но глубже копать у меня уже мотивации не было, т.к. проблема ушла после снятия одной галочки, а весь установленный софт мне все равно нужен для работы.


                                      В общем,
                                      TLDR; Если включена смена фонов рабочего стола и выбор цвета акцента в зависимости от фона — попробуйте что-то из этого отключить.

                                        0
                                        Нет, у меня на рабочем столе Стармен на фоне Земли, давно уже.
                                        Последнюю неделю тормоза не выплывали ни разу. Не знаю точно с чем связано — слишком много переменных. Во-первых отключил (как минимум временно) Windows Defender. Периодически наблюдал, что он на постоянку выжирает 30-40% CPU, правда его временное отключение ситуации с тормозами не меняло, но не уверен. Во-вторых за неделю несколько раз накатывались апдейты на винду и студию, приходилось перезагружаться.
                                        Продолжаю наблюдение.
                                      0

                                      Любопытно, что 1,6 — это приблизительное значение золотого сечения

                                        0
                                        Больше интересно другое. Сами разработчики windows, выходит, не сталкиваются с этой проблемой при сборках своих продуктов, так? Или они никогда не собирают на своих машинах?
                                          +1
                                          Лет десять назад писали, что сборка Windows идёт на серверной ферме раз в неделю.
                                            0
                                            Судя по номерам билдов, сейчас деоа обстоят несколько иначе.
                                            +2

                                            Возможно, им просто не приходит к голову запускать раз в час проверку репозитория. Я так не понял из статьи, зачем это было сделано.

                                              0

                                              А это не дефолтное поведение Винды? Надо бы в Планировщике такую задачу поискать.

                                                0

                                                Не вижу у себя такой задачи.


                                                Для дефолтного поведения это очень странная идея: WMI Repository обновляется, как правило, только с обновлениями винды. Зачем его вообще проверять раз в час?

                                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                          Самое читаемое