Зомби, которые съедают вашу память

https://randomascii.wordpress.com/2018/02/11/zombie-processes-are-eating-your-memory/
  • Перевод
  • Tutorial
Что бы вы там себе не думали, а зомби существуют. И они действительно едят мозги. Не человеческие, правда, а компьютерные. Я говорю сейчас о зомби-процессах и потребляемых ими ресурсах. Это будет душераздирающая история о потерянных и снова найденных 32 ГБ оперативной памяти. Возможно, лишь некоторые из вас столкнутся с точно такой же проблемой, но если вдруг это произойдёт — у вас хотя бы будет шанс понять, что происходит.

Начнём с того, что компьютеры под управлением ОС Windows склонны со временем терять память. Ну, по крайней мере, у меня, при моём способе ими пользоваться. После пары недель без перезагрузок (или, например, всего одного уикэнда за который я 300 раз пересобрал Хром) я стал замечать, что диспетчер задач начинает показывать мне очень маленькое количество свободной оперативной памяти, но в то же время в системе нет никаких процессов, которые эту самую память активно используют. В том примере выше (с 300 сборками Хрома) диспетчер задач сказал мне, что в системе занято 49.8 ГБ плюс ещё 4.4 ГБ памяти сжато — но при этом запущено всего несколько процессов, и все они в сумме даже и близко не используют столько памяти:

image

В моём компьютере 96 ГБ оперативной памяти (да, я счастливчик) и когда у меня нет вообще никаких запущенных процессов — я, знаете ли, хотел бы видеть ну хотя бы половину этой памяти свободной. Я правда рассчитываю на это. Но иногда этого достичь не удаётся и мне приходится перезагружать ОС. Ядро Windows написано качественно и надёжно (без шуток), так что память не должна бы пропадать бесследно. Но всё же она пропадает.

Первой же моей догадкой стало воспоминание о том, что один из моих коллег как-то жаловался на зомби-процессы, которые иногда остаются в ОС уже не активными, но всё же ещё не до конца удалёнными ядром. Он даже написал специальную утилиту, которая выводит список таких процессов — их имена и количество. Когда он запускал эту утилиту в своих тестах, то получал до нескольких сотен зомби-процессов на обычной Windows-машине. Я нашел его инструмент, запустил на своём компьютере и получил… 506 000 зомби-процессов. Да, 506 тысяч!

Я вспомнил, что одной из возможных причин перехода процесса в состояние «зомби» может быть то, что какой-то другой процесс держит открытым его дескриптор (handle). В моём случае большое количество зомби-процессов играло мне на руку — им было сложнее скрыться. Я просто открыл диспетчер задач и добавил на вкладку Details столбец с количеством открытых дескрипторов для каждого процесса. Затем отсортировал список по убыванию значений в этом столбце. Я сразу нашел героя данной истории — процесс CcmExec.exe (часть Microsoft System Management Server) имел 508 000 открытых дескрипторов. Это было во-первых, очень много, а во-вторых, подозрительно близко к найдненному мною выше числу в 506 000 зомби-процессов.

image

Я убил процесс CcmExec.exe и получил следующий результат:

image

Всё получилось ровно так, как я того и ожидал. Как я без иронии писал выше — ядро Windows написано очень хорошо и когда процесс уничтожается, то и все занятые им ресурсы освобождаются. Закрытие CcmExec.exe освободило 508 000 дескрипторов, что дало возможность окончательно закрыть 506 000 зомби-процессов. Количество свободной оперативной памяти мгновенно выросло на 32 ГБ. Тайна раскрыта!

Что такое зомби-процесс?


До этого момента мы ещё не выяснили, что же заставило все эти процессы зависнуть в неопределённости, а не быть удалёнными. Похоже на то, что мы имеем дело с тривиальным багом в приложении (а не в ядре ОС). Общее правило гласит, что когда вы создаёте процесс, то получаете его дескриптор и дескриптор его главного потока. Вы ОБЯЗАНЫ закрыть эти дескрипторы. Если вашей задачей было просто запустить процесс — их можно закрыть сразу же (это не убъёт запущенный процесс, а просто разорвёт связь вашего процесса с ним). Если новый процесс вам для чего-то нужен (например, вы ждёте окончания его работы или вам нужен код, который он вернёт) — то нужно воспользоваться соответствующими функциями (например, WaitForSingleObject(hProcess, INFINITE) для ожидания выхода или GetExitCodeProcess(hProcess, &exitCode) для получения кода возврата) и всё-равно закрыть дескрипторы после того, как вы получили от дочернего процесса всё, чего хотели. Аналогично следует и поступать и с дескрипторами процессов, которые вы для чего-нибудь открываете с помощью функции OpenProcess().

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

Куда же девается память?


Ещё одним инструментом, который я использовал в своём исследовании, была утилита RamMap. Она показывает использование каждой страницы памяти. На вкладке Process Memory мы видим сотни тысяч процессов, каждый из которых занимает 32 КБ оперативной памяти — очевидно, это и есть наши зомби. Но ~500 000 раз по 32 КБ будет равно примерно 16 ГБ — куда же делась остальная память? Сравнение состояния памяти до и после закрытия зомби-процессов даёт ответ на этот вопрос:

image

Мы можем чётко увидеть, что ~16 ГБ уходит на Process Private Memory. Также мы видит, что ещё 16 ГБ приходится на Page Table Memory. Очевидно, что каждый зомби-процесс занимает 32 КБ в таблице страниц памяти и еще 32 КБ использует для своей личной памяти. Я не знаю для чего зомби-процессу так много памяти, но, наверное, никто никогда не думал, что число таких процессов может измеряться сотнями тысяч.

Некоторые типы занятой памяти увеличились после закрытия процесса CcmExec.exe, в основном это касается Mapped File и Metafile. Я не знаю точно, почему так получилось. Одной из моих догадок является то, что ОС решила, что свободной памяти теперь достаточно и что-то себе закешировала. Это, в общем, не плохо. Мне не жаль памяти для нужд ОС, я просто не хочу, чтобы она пропадала совсем уж бесцельно.

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

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

Я надеюсь, что данная проблема будет скоро исправлена.

Почему у меня на компьютере возникают такие странные проблемы?


Я работаю над кодом Windows-версии Хрома и одной из моих задач является оптимизация его сборки на этой ОС, а это требует многократных запусков этой самой сборки. Каждая сборка Хрома запускает огромное множество процессов — от 28 000 до 37 000 в зависимости от выбранных настроек. При использовании нашей распределённой системы сборки (goma) эти процессы создаются и закрываются очень быстро. Мой лучший результат сборки Хрома — 200 секунд. Но столь агрессивная политика запуска процессов выявляет и проблемы в ядре Windows и её компонентах:

  • Быстрое удаление процессов ведёт к зависаниям пользовательского ввода
  • Драйвер тачпада выделяет, но не освобождает память при каждом создании процесса
  • App Verifier создаёт O(n^2) лог-файлов (и об этом стоит написать отдельный пост!)
  • Есть баг в ядре Windows, который касается буферизации файлов, и этот баг воспроизводится на всех Windows от Server 2008 R2 до Windows 10
  • Windows Defender задерживает запуск каждого процесса goma на 250 мс

Что дальше?


Если вы работаете не на компьютере, управляемом политиками компании, то процесс CmmExec.exe у вас не запущен и с конкретно данным багом вы не столкнётесь. Также он коснётся вас только если вы собираете Хром или делаете ещё что-то похожее, создавая и закрывая при этом десятки тысяч процессов в короткие промежутки времени.

Но!

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

Как знают все опытные программисты, любая ошибка, которая не была явно исправлена или предупреждена — точно когда-то произойдёт. Просто написать в документации «Пожалуйста, закройте этот дескриптор» — не достаточно. Так что вот мой вклад в то, чтобы сделать нахождение подобного типа ошибок проще, а их исправление — реальнее. FindZombieHandles — это инструмент, основанный на NtApiDotNet и коде от @tiraniddo, который выводит список зомби-процессов и информацию о том, кто сделал их зомби. Вот пример вывода данной утилиты, запущенной на моём компьютере:

274 total zombie processes.
249 zombies held by IntelCpHeciSvc.exe(9428)
249 zombies of Video.UI.exe
14 zombies held by RuntimeBroker.exe(10784)
11 zombies of MicrosoftEdgeCP.exe
3 zombies of MicrosoftEdge.exe
8 zombies held by svchost.exe(8012)
4 zombies of ServiceHub.IdentityHost.exe
2 zombies of cmd.exe
2 zombies of vs_installerservice.exe
3 zombies held by explorer.exe(7908)
3 zombies of MicrosoftEdge.exe
1 zombie held by devenv.exe(24284)
1 zombie of MSBuild.exe
1 zombie held by SynTPEnh.exe(10220)
1 zombie of SynTPEnh.exe
1 zombie held by tphkload.exe(5068)
1 zombie of tpnumlkd.exe
1 zombie held by svchost.exe(1872)
1 zombie of userinit.exe

274 зомби — это ещё не так плохо. Но уже и это указывает на определённые проблемы, которые могут быть найденны и исправлены. Процесс IntelCpHeciSvc.exe в этом списке имеет самые большие проблемы — похоже на то, что он открывает (и забывает закрыть) дескриптор процесса каждый раз, когда я открываю видео в Windows Explorer.

Visual Studio забывает закрыть дескрипторы как минимум двух процессов, в одном случае это воспроизводится всегда. Просто запустите сборку проекта и подождите ~15 минут пока процесс MSBuild.exe закроется. Можно также выставить опцию “set MSBUILDDISABLENODEREUSE=1” и тогда MSBuild.exe закроется сразу по окончанию сборки и потерянный дескриптор будет виден сразу. К сожалению, какой-то негодяй в Microsoft исправил эту проблему и фикс должен выйти в обновлении VS 15.6, так что поторопитесь воспроизвести её, пока это ещё работает (надеюсь, не нужно объяснять, что это была шутка и никакой он на самом деле не негодяй).

Также вы можете использовать для просмотра забытых процессов программу Process Explorer, сконфигурировав её нижнюю панель так, как это показано ниже (заметьте, что в этом случае будут показаны забытые дескрипторы как для процессов, так и для потоков):

image

Вот пару примеров найденных багов (о некоторых сообщено разработчикам, но не о всех):

  • Утечка в CcmExec.exe (описанный выше случай с 500 000 зомби) — разработчики работают над исправлением
  • Утечка в Program Compatibility Assistant Service — проблема исследуется
  • Утечка в devenv.exe + MSBuild.exe (проблема уже исправлена)
  • Утечка в devenv.exe + ServiceHub.Host.Node.x86.exe (багрепорт отправлен)
  • Утечка в IntelCpHeciSvc.exe + Video.UI.exe для каждого открытого видеофайла (Intel приняла багрепорт и переслала его в Lenovo)
  • Утечка в RuntimeBroker.exe + MicrosoftEdge и Video.UI.exe (возможно, имеет отношение к некоторым другим багам в RuntimeBroker.exe)
  • Утечка в AudioSrv + Video.UI.exe
  • Утечка в одном внутреннем инструменте Google из-за использования старой версии psutil
  • Утечка в утилитах от Lenovo: tphkload.exe теряет один дескриптор, SUService.exe теряет три
  • Утечка в Synaptic’s SynTPEnh.exe

Дескрипторы процессов — не единственный тип ресурсов, который может утекать таким образом. Например, “Intel® Online Connect Access service” (IntelTechnologyAccessService.exe) использует всего 4 МБ оперативной памяти, но, будучи запущенной 30 дней, создаёт 27 504 дескрипторов. Эту проблему можно обнаружить с помощью Диспетчера Задач, я отправил разработчикам багрепорт о ней:

image

Используя Process Explorer, я заметил, что NVDisplay.Container.exe открывает ~5000 дескрипторов на событие \BaseNamedObjects\NvXDSyncStop-61F8EBFF-D414-46A7-90AE-98DD58E4BC99, создавая новый дескриптор каждые две минуты. Я так понимаю, они хотят быть супер-уверены в том, что могут остановить NvXDSync? Багрепорт Nvidia отправлен.

image

Corsair Link Service создаёт ~15 дескрипторов в секунду, не освобождает их совсем. Багрепорт отправлен.

Adobe’s Creative Cloud теряет тысячи дескрипторов (около 6500 в день, по моим подсчётам). Багрепорт отправлен.

Razer Chroma SDK Service теряет ОЧЕНЬ много дескрипторов (150 000 в час?). Багрепорт отправлен.

Удивительно, что никто до этого особо не обращал внимание на подобные баги. Эй, Microsoft, возможно, стоит собирать статистику по таким случаям и что-то предпринимать по этому поводу? Эй, Intel и Nvidia, почистите немного ваш код. Помните, я наблюдаю за вами.

А теперь вы можете взять утилиту FindZombieHandles, запустить её на вашей машине и рассказать о своих находках. Также вы можете использовать в экспериментах диспетчер задач и Process Explorer.
Инфопульс Украина 164,74
Creating Value, Delivering Excellence
Поделиться публикацией
Комментарии 92
  • +1
    0 total zombie processes.
    No zombies found. Maybe all software is working correctly...

    Меня несколько лет назад, тоже интересовала эта тема, думая вам стоит ознакомиться с superfech. В реальности она будет кушать ровно столько памяти, сколько доступно. Проверял на машинках с 4, 16 и 32 Гб памяти, ОС Win7 и 8.1.
    В некоторых случаях, её есть смысл отключать, работает не так как хотелось бы. Например на тех же компиляциях при наличии ссд.
    • 0
      Я отключал… не помогает. После одного-двух уходов в сон потребление памяти снова доходит до 7+ГБ из 7,9ГБ полного объема. При этом стартует система с потреблением 4-5ГБ.
    • 0
      RamMap не запустился, у вас недостаточно памяти для запуска приложения ЛОЛ
      при этом тот же текучий хром запущен успешно поедает память
      • +1
        0 total zombie processes.
        No zombies found. Maybe all software is working correctly, but I doubt it. More likely the zombie counting process failed for some reason. Please try again.
        • 0
          1731 total zombie processes.
          Количество постепенно растёт. Браузер закрыт. Win10, x64.
          Пока писал этот коммент 5 зомбей прибавилось.
          • –5
            Это кошмар, ребятки.
            Колоссальные усилия для поиска зомби. Ваш коллега написал утилиту, вы в ручную ставили множество других программ и нетривиально находили эти процессы.
            В процессе нашли несколько багов в самой винде, так еще и утечку в более чем 10 популярных приложений.
            Что-то в этом виндовс-мирке точно не так.
            • +3
              Что-то в этом виндовс-мирке точно не так.

              Если что в юниксовых системах тоже существуют процессы-зомби.
              Выходит, в юникс-мирке что-то не так тоже?
              • –1
                Они существуют. Но их показывает ps и поэтому очень непросто заметить приложение, которое их плодит. У на машине сейчас только pidgin таким страдает.
                • +1
                  К сожалению Unix-мир зря гордится. Зомби в Unix-мире заметны сразу, так что 500'000 штук никто не оставит.

                  Но вот всякое добро внутри X сервера, оставленное там «умершими» программами или ошмётки от криво реализованного IPC (который не освобождает ресурсы, если программа забывает это делать) — приводят примерно к такому же эффекту.

                  Увы, но нет в мире операционок без подобных эффектов. Android к этому стремится (в частности поэтому он не поддерживает POSIX IPC), но… он тоже идеала пока не достиг…

                  P.S. Причём заметим, что в случае с POSIX IPC всё хуже — реализовно оно в ядре и API там такой, что избавиться от утечек в принципе нельзя. По крайней мере разработчики Windows могут гордится тем, что ядро «не теряет» память…
                  • 0
                    Справедливости ряди, это скорее к Sytem V IPC относится. В POSIX чуть лучше — объекты освобождаются как только больше не нужны ни одному процессу.

                    А так ещё открытые, удалённые с диска, файлы можно припомнить. Тоже в своём роде утечка места.
              • 0
                Оставлю тут — www.cvedetails.com/top-50-products.php?year=2016
                С годами ТОП меняется, но Linux там явно не среди последних.
              • –1

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

                • +3
                  Не совсем. Нужно выполнить waitpid(childPid, &returnStatus, 0); в обработчике SIGCHILD или без него. Иначе получим такого-же зомби. Тут скорее фактор, что зомби сразу же видны в top, потому таких ошибок меньше.
                  • +1
                    Насколько я понимаю аналогичный api в unix, то там нет блока: умер процесс, родителя об этом уведомили, а если он не среагировал, это его проблемы.
                    Будет зомби — точно так же, как в Windows. Просто эти зомби будут в списке процессов видны, это заметят и будут чинить.

                    Разница не в подходе, а в средствах диагностики…
                    • 0

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

                      • +1
                        Нельзя просто так взять и отнять дескриптор у процесса, точнее, можно, но процессу это может не понравится. Может он действительно нужен для каких-то своих целей, даже после закрытия?
                        • +4
                          Наверняка есть причина такого поведения.
                          Да, конечно. Как вы будете систему сборки писать, если вы не можете узнать — завершилась команда компиляции с ошибкой или нет?

                          От зомби нужно, по большому счёту, две вещи:
                          1. Запомнить код возврата (чтобы родитель смог понять — отработал процесс-потомок успешно или нет).
                          2. Слот в таблице процессов (так как если этого не сделать, то, опять-таки, невозможно будет говорить о коде возврата процесса с заданным PID'ом… их ведь может быть много, если в системе нет понятия «зомби»).

                          Так как обычно зомби долго не живут, то оставить для них один несколько больше информации — не очень страшно, но очень сильно помогает для «посмертного анализа» (если зомби вовремя не умирают, то возможность понять — что это за процессы и как они были запущены — очень полезна).
                        • 0
                          Всё ж в Linux зомби чуть более мирные. Остаётся только лишняя запись в таблице процессов. Бывшая память зомби процесса уже свободна.
                          Правда в результате может быть переполнение таблицы процессов… Так что увы.
                          • +1
                            Всё ж в Linux зомби чуть более мирные. Остаётся только лишняя запись в таблице процессов.
                            Не только. Вроде бы ещё в ядре какое-то количество структур остаётся. 8K, если память не изменяет. Что, конечно, в 4 раза меньше, чем в Windows… но всё равно довольно много.
                      • –2
                        Теперь понятно почему хром такой прожорливый. Вот если бы у его разработчиков было не по 50 гигов, а 8 или даже 4, то они бы чаще обращали внимание на проблемы с памятью. А то запустил пару-тройку приложений на электроне + сам хром и уже 6-7 гигов как не бывало!
                        • +3
                          Им память нужна для сборки, иначе компилировать они его будут месяц.
                          • +3
                            Это понятно. Просто когда постоянно живёшь в достатке ресурсов, то проблемы «третьего мира» начинают казаться несущественными. Подозреваю что сборки тестируются в том числе на ограниченных конфигурациях, но вряд ли основная масса разаработчиков постоянно живёт в таких условиях. Из-за этого может формироваться мнение, что раз нормально работает у меня локально, то и у всех будет так же.
                            • 0
                              Такое количество памяти требуется для разработки, а не для тестирования.

                              Например у меня на машине 8 гигов, и если я при загрузке винды запущу любое приложение, например браузер с двумя вкладками, то докеру не хватит памяти и он не сможет запуститься. То есть в моем случае 16 гигов — это МИНИМУМ, без которого всему необходимому мне для разработке софту не хватит места для запуска.

                              Так что это физически невозможно, да и не нужно.
                              • +1
                                Если б они полноценно тестировались на «ограниченных конфигурациях», вряд ли браузеры подлагивали на i3 и тормозили на atom'ах.
                                • –1
                                  Скорее у них другое представление о «нормальной» работе. Они запускают штук 10 окон в браузере, лениво сёрфят полдня и считают работу зачтённой, если это не крашится и не улетает в лютые тормоза. Роль бет исполнят простые юзьвери, им не привыкать, они же пусть и делают статистические и структурные анализы потребления памяти, обращений к диску, загрузки проца и сетевых запросов. Сплошная экономия, так ещё и чувство сопричастности к процессу разработки за «спасибо». :)
                                • 0
                                  Компилировать — нет, для этого много памяти не нужно. А вот линкер при сборке Хрома может десятки гигабайт в одиночку выжирать…
                                  • 0
                                    На виртуалке с 8 ГБ и обычным HDD у меня собирается где-то пол часа.
                                  • +5
                                    то они бы чаще обращали внимание на проблемы с памятью.

                                    Они обращают, и очень активно. В Chromium есть специальная Memory Team, состоящая из инженеров Google и Opera, которая занимается выяснениями «на что тратится память» (в столь большом и сложном проекте подобный вопрос тянет не на одно исследование) и оптимизациями всего этого дела. Результаты у них может и не впечатляющие, но значительные.
                                    Плюс от разработчиков V8 периодически тоже приходят новости об успехах по этой части.
                                    и уже 6-7 гигов как не бывало

                                    Это нормально. Точнее сказать, так и должно быть. У Chromium сознательная политика вида «если есть память, нужно ее использовать под кэши/буферы/другие в определенной степени полезные вещи». Внутри браузере есть механизм определения так называемого 'memory pressure', и когда памяти в системе становится маловато (уровень 'moderate') или совсем мало (уровень 'critical'), компонентам браузера рассылается уведомление, что не мешало бы почиститься и ужаться.
                                    Обычный пользователь может прикоснуться и даже немного повлиять на эту магию с помощью опций, начинающихся с --memory-pressure* в командной строке, поглядите, там разные параметры есть.
                                    Сейчас все это дело еще перепиливается, решения об оптимизации потребления ОЗУ во время выполнения и выгрузке различных данных будут применяться также исходя из пользовательской активности и других факторов, процесс еще не завершен, но вообще будет много интересного.
                                    • 0
                                      Может быть и обращают.
                                      Но по моим наблюдениям, когда памяти остаётся маловато или совсем мало, у хрома начинаются серьёзные проблемы.
                                      Начиная с задержек отрисовки табов в заголовке окна и заканчивая сообщениями «Вкладка не отвечает» после попытки открыть новую пустую (!) вкладку.
                                      • 0
                                        Новая пустая вкладка вообще-то запускает целый новый процесс — со всеми вытекающими.
                                      • 0
                                        С другой стороны, у меня теперь сознательная политика — не использовать Chrome, не ставить его и предлагать всем его удалить.
                                        • 0
                                          А что в замен? Только хромопроизводные и остались. Не считать же развалины FF или Edge за браузеры.
                                          • 0
                                            Мой FF 40, прям возмутился отображая этот камент.
                                            • 0
                                              40 конечно ещё нормальная версия, сам на производном от 55 сижу, но я про современные версии.
                                        • 0
                                          А этот «memory pressure» может определить, что, несмотря на работавший целый день браузер, вот именно сейчас 6гб памяти нужно только что запущенной игре?
                                        • –2
                                          А Вы ещё пользуетесь хромом??? Я его поставил себе, использовал несколько дней, заметил, что комп стал работать сильно медленнее, открыл диспетчер задач, увидел, что большую часть памяти и процессора жрёт именно хром. Снёс хром — с тех пор комп просто летает.
                                        • 0
                                          А теперь вы можете взять утилиту FindZombieHandles, запустить её на вашей машине и рассказать о своих находках.

                                          Требует .NETFramework 4.5, увы. Впрочем, на моей XP x64 редко у какого процесса есть больше 1000 дескрипторов, и зомби процессов и памяти я там не наблюдаю.
                                          • 0
                                            .нет 4.5 уже не ставится на ХР или это из-за мало совместимого х64 у ХР?
                                          • 0
                                            Попробуйте пересобрать под более старый .NET. Там же ничего кроме P/Invoke не используется… Еще можно попробовать под Mono запустить. Или конфиг исправить, чтобы .NET 4.0 использовался, он под XP есть.
                                            • 0
                                              Не, бесполезно. Там все проблемы в библиотеке NtApiDotNet, не знаю, как это им удаётся, но компилироваться под 4.0 она никак не хочет, хотя казалось бы, простой враппер для функций.
                                              Конфиг правил, не катит.
                                              • 0
                                                Там надо, видимо, асинхронные функции порезать. Или библиотеку с реализацией асинхронности подключить.

                                                А что говорит Mono?
                                                • 0
                                                  Там надо, видимо, асинхронные функции порезать. Или библиотеку с реализацией асинхронности подключить.

                                                  Да, несостыковки вылазили как раз на async с await. А какие библиотеки есть?
                                                  А что говорит Mono?

                                                  Не знаю, с какой стороны к нему подступится, но на странице загрузки есть только Supported on Windows 7, 8, 10 or later. Сейчас посмотрю старые версии, но вряд ли что выйдет.
                                                  • 0
                                                    Тогда Microsoft.Bcl.Async
                                                    • 0
                                                      Так, хорошо, уже запустилось, правда пришлось пару методов «зануллить». На десятке работает и показывает значения, равные оригиналу, но на XP ругается на отсутствие привилегии отладки и не может импортировать NtGetNextProcess из ntdll. Такая функция в XP должна быть, судя по WRK, но не экспортируется.
                                                      Ладно, спасибо за помощь.
                                          • 0
                                            4 total zombie processes.
                                                1 zombie held by Dropbox.exe(7120)
                                                    1 zombie of chrome.exe
                                                1 zombie held by svchost.exe(1320)
                                                    1 zombie of userinit.exe
                                            Pass -verbose to get full zombie names.

                                            Пожалуй помониторю пару дней. Уже не раз обращал внимание на «потери» памяти, грешил на возможные зловреды, но ни разу словить в AVZ/Gmer не удавалось. Может и правда дело в зомбях.
                                            • 0
                                              Десяток зомбей сожруть меньше мегабайта памяти. Чтобы беда случилась их должны быть тысячи…
                                              • 0
                                                Потому и говорю что помониторю, утром ОС ребуталась и уже 4 зомби, хотя я еще толком на компе ничего не делал.
                                                • 0
                                                  Как я писал выше: появление (и исчезновение) зомби — это нормально. Ненормально — это когда они «зависают» в «полумёртвом» состоянии на часы (а то и дни).
                                            • 0
                                              У меня вывод handle не совпадает с кол-вом открытых дескрипторов:
                                              image
                                              D:\Work>handle.exe -p 4268 | wc -l
                                              30

                                              Интересно, почему…
                                              Если что — это Windows 7. Также пробовал на Windows 10, там тоже на порядки отличается.
                                              • +1

                                                Так она же только зомби считает, а не все открытые хэндлы.

                                              • 0
                                                Nthandle v4.11 — Handle viewer
                                                Copyright © 1997-2017 Mark Russinovich
                                                Sysinternals — www.sysinternals.com

                                                usage: handle [[-a [-l]] [-u] | [-c [-y]] | [-s]] [-p |] [name] [-nobanner]
                                                -a Dump all handle information.
                                                -l Just show pagefile-backed section handles.
                                                -c Closes the specified handle (interpreted as a hexadecimal number).
                                                You must specify the process by its PID.
                                                WARNING: Closing handles can cause application or system instability.
                                                -y Don't prompt for close handle confirmation.
                                                -s Print count of each type of handle open.
                                                -u Show the owning user name when searching for handles.
                                                -p Dump handles belonging to process (partial name accepted).
                                                name Search for handles to objects with (fragment accepted).
                                                -nobanner Do not display the startup banner and copyright message.

                                                No arguments will dump all file references.

                                                Надо было
                                                handle -a -nobanner -p 4268 | wc -l

                                                или
                                                handle -s -nobanner -p 4268
                                                • 0
                                                  Посыпал голову пеплом. Спасибо!
                                              • 0
                                                А у меня вот Reeder запускает на каждый просмотр страницы внутри себя Safari, и похоже, забывает их правильно закрывать.

                                                В итоге, ест память больше хрома
                                                • 0
                                                  geektimes.ru/post/107605
                                                  geektimes.ru/post/107607
                                                  geektimes.ru/post/107637
                                                  Это уже почтенного возраста статья конечно. Но как я вижу актуальности не теряет. Да и по сей день встречаются толпы людей из «тёмного царства», нуждающиеся в лучиках света.
                                                  Поток людей, творящих чёрт знает что с памятью не уменьшается со временем.

                                                  Последнее что видел буквально с месяц назад — как у клиентов вырубается виртуальная машина выполняющая роль терминала для 20 учетных записей. Ей отвели всего-навсего 384 Мб ОЗУ в VMWare (ОС WinServ2003). Один клиент съедает 804 Мб ОЗУ. Даже один клиент заставляет машину жить в жОстком свопе. Что происходит при подключении 20 клиентов… ну то что происходит, машина умирает. Хорошо когда люди включают голову, хотя бы иногда, при настройке софта и выборе нагрузок на железо!
                                                  • –13
                                                    Глубокое отвращение к продуктам Microsoft не позволяет мне тратить время на подобные расследования. Однако, могу отметить, в линуксе зомби мозги память не жрут, просто ходят и жалобно мычат.
                                                  • 0
                                                    App Verifier создаёт O(n^2) лог-файлов (и об этом стоит написать отдельный пост!)

                                                    Судя по твиту — он создает ровно n файлов. А вот времени на это тратит таки O(n^2)

                                                    • 0
                                                      ой, ой.
                                                      WARNING: Can't enable debug privilege. Some zombies may not be found. Run as admin for full results.
                                                      227 total zombie processes.
                                                      185 zombies held by svchost(11768)
                                                      93 zombies of chrome.exe
                                                      17 zombies of ServiceHub.RoslynCodeAnalysisService32.exe
                                                      15 zombies of ServiceHub.IdentityHost.exe
                                                      14 zombies of Node.exe
                                                      9 zombies of ServiceHub.Host.CLR.x86.exe
                                                      8 zombies of ServiceHub.VSDetouredHost.exe
                                                      8 zombies of ServiceHub.SettingsHost.exe
                                                      6 zombies of ServiceHub.DataWarehouseHost.exe
                                                      3 zombies of Microsoft.VsHub.Server.HttpHost.exe
                                                      2 zombies of software_reporter_tool.exe
                                                      2 zombies of software_reporter_tool.exe
                                                      2 zombies of RdrCEF.exe
                                                      2 zombies of phantomjs.exe
                                                      2 zombies of conhost.exe
                                                      1 zombie of Code.exe
                                                      1 zombie of AcroRd32.exe
                                                      22 zombies held by svchost(3696)
                                                      22 zombies of RAVBg64.exe
                                                      12 zombies held by IntelCpHeciSvc(7224)
                                                      4 zombies of Video.UI.exe
                                                      4 zombies of Video.UI.exe
                                                      4 zombies of Video.UI.exe
                                                      3 zombies held by devenv.exe(28936)
                                                      2 zombies of ServiceHub.Host.Node.x86.exe
                                                      1 zombie of MSBuild.exe
                                                      1 zombie held by SynTPEnh.exe(27400)
                                                      1 zombie of SynTPEnh.exe
                                                      1 zombie held by sihost.exe(16604)
                                                      1 zombie of backgroundTaskHost.exe
                                                      1 zombie held by svchost(2232)
                                                      1 zombie of userinit.exe
                                                      Pass -verbose to get full zombie n

                                                      P.S. chrome.exe даже не запускался.
                                                      • –2
                                                        Автор, безусловно, путает процессы и хэндлы. Будь у него 506 тысяч зависших процессов — большинство PID'ов давно стало бы шести-и семизначными.
                                                        • +3
                                                          В ссылке на твиттер (выше): «Also my PIDs are well into the 2,000,000 range.»
                                                        • 0
                                                          Всего лишь 202 зомби, хотя не перегружался неделю и в студии постоянно открываю тяжеловесные проекты (хотя прямо говоря — да, приходится порой студию из процессов убивать, т.к. держит файлы)
                                                          • –1
                                                            Вы бы хоть версию винды писали, можно было бы как-то статистику организовать. В конце концов, выяснить, в какой момент мелкомягкие ушли в грех.

                                                            У меня, например, на 8.1 пусто после 8-часовой работы в Qt с периодическими инкриментальными сборками студией и мингвой.
                                                            • 0
                                                              Простите далекого от этого, но вот я с гита слил репу, нахожусь в директории с «программой», но что с этим делать дальше? Можно на пальцах? Как это вообще запускается?
                                                              • 0
                                                                Зайдите в папку prebuilt — там бинарники лежат.

                                                                А вообще, для сборки проекта надо поставить Microsoft Build Tools 2017, после чего запустить из командной строки msbuild находясь в папке проекта — он соберет.
                                                                • –1
                                                                  Все, теперь понял.
                                                                  *Я просто из java-world, а в статье это не отражено:
                                                                  А вообще, для сборки проекта надо поставить Microsoft Build Tools 2017, после чего запустить из командной строки msbuild находясь в папке проекта — он соберет.

                                                                  и для «левого» человека данные моменты могут являться не очевидными.
                                                                  • 0
                                                                    Для «левых» людей в репозитории есть папка prebuilt :-)
                                                                    • 0
                                                                      Опять же, мне, левому человеку, это название ни о чем не говорит.
                                                                      И да, я программист. Но ЯП иной и своя компоновка как директорий, так и наименований.
                                                                      С моей колокольни тут будет «что-угодно», но не результат работы компилятора… скорее сорцы/компоненты, ибо стоит pre (prepared for build?!).

                                                                      А так, наш диалог — наглядная иллюстрация «ожидание vs реальность».

                                                                      P.S. У меня, к примеру, «выхлоп» идет в директорию target — так же абсолютно не очевидно, что туда будет собран результат компиляции… ибо ну папка с именем «цель», а чего «цель» не понятно. (тут смайлик «развожу руками»)
                                                                      • 0
                                                                        Не волнуйтесь, у нас тоже своя компоновка директорий. Бинарники оказываются в папке bin.

                                                                        А prebuilt — это авторское изобретение в конкретном репозитории, сделанное человеком который не разобрался зачем на гитхабе придуманы релизы. Переводится как «заранее построенное».
                                                                        • 0
                                                                          «Век живи — век учись» (с).
                                                                          Еще раз вам спасибо за помощь!
                                                                          • –2
                                                                            А prebuilt — это авторское изобретение в конкретном репозитории,
                                                                            Да ладно вам? А это тогда о чём?

                                                                            prebuilt — это стандартное название для таких вещей. В Android мире как минимум.

                                                                            сделанное человеком который не разобрался зачем на гитхабе придуманы релизы.
                                                                            Нет, всё проще — это сделано человеком, который github'ом пользуется только изредка и не хочет менять своих привычек. AOSP'шный prebuilt жил тут ещё 10 лет назад (потом его на части разбили, правда).
                                                                            • 0
                                                                              По первой вашей ссылке нет ничего про структуру директорий в репозитории. По второй я вижу отдельный репозиторий для бинарников. Это нормальная практика, в отличии от хранения всего в одной репе вперемешку.

                                                                              Что же до слова «prebuilt» — я бы вам поверил что оно существует и без ссылок :-) Под авторским изобретением я понимал элемент структуры директорий, а не слово в отрыве от нее.
                                                                              • 0
                                                                                По первой вашей ссылке нет ничего про структуру директорий в репозитории.
                                                                                Потому что git не поддерживает прав доступа. «Структура директорий» описана тут и собирается с помощью repo.

                                                                                Это нормальная практика, в отличии от хранения всего в одной репе вперемешку.
                                                                                Там где нет проблем с правами доступа и проект небольшой — там всё вместе. Вот пример. Вот ещё один. Во втором случае — как раз ситуация, когда было решено, что пора на googlestorage вынести пребилды…

                                                                                Под авторским изобретением я понимал элемент структуры директорий, а не слово в отрыве от нее.
                                                                                Ещё раз: это не авторское изобретение. Это стандартная практика в гугловых проектах.
                                                                                • 0
                                                                                  А вот это они зря…
                                                                                  • 0
                                                                                    Почему зря? Это удобно и просто. Проблема только в том, что git не очень хорошо работает с бинарными файлами, так что для больших проектов это не годится.
                                                                                    • 0
                                                                                      Это крайне неудобно: нужно в обязательном порядке собирать проект перед каждым коммитом, иначе бинарники окажется нерелевантными. А значит — нужно сначала найти инструкции по сборке всей этой радости (а может быть — даже ОС сменить, тут не проверял).

                                                                                      А потом при каждом слиянии — будут лезть конфликты.
                                                                                      • 0
                                                                                        Всё гораздо проще: это делает Commit-Queue бот. И только в основную ветку.

                                                                                        Чем это, собственно, отличается от других методов выпуска релизов?

                                                                                        P.S. Конечно если вам нужно собирать под разные платформы на разных ботах — этот метод неудобен, это да.
                                                                                        • 0
                                                                                          Отлично, значит разные файлы в одном и том же коммите могут не соответствовать друг другу…

                                                                                          Дело не в методе выпуска релиза, а в методе публикации. Основной репозиторий git — неподходящее место для этого.
                                                                          • 0
                                                                            И да, я программист. Но ЯП иной и своя компоновка как директорий, так и наименований.

                                                                            Я вообще PHPшник, где сборка отсутствует как класс. Что не помешало мне потыкать по каталогам и найти бинарник, убедится в том, что он не запускается на XP, поставить студию, сменить версию дотнета, и совершить ещё множество действий при практически полном непонимании синтаксиса, компоновки и прочего.
                                                                            • 0
                                                                              Я из тех, кто сначала «читает ман, потом тыкает/делает».
                                                                              Мана нет (Readme), названия не понятные. Пошел спрашивать.
                                                                            • 0
                                                                              Приставка «pre-» — значит «перед, предварительно». «built» — это «собранный». «prebuilt» — «предварительно собранный». Ну в общем, точно не сорцы.
                                                                    • 0
                                                                      Вопрос: если есть механизм отслеживания количества зомби процессов под виндой — то можно ведь встроить этот механизм непосредственно в ОС, собирать статистику и отправлять непосредственно разработчикам.

                                                                      Так же если честно не очень понятно, как можно определить что определенный процесс является зомби, он ведь может ждать какого то определенного события, пусть даже несколько дней.
                                                                      • +2
                                                                        Зомби уже ничего «ждать» не может. У него завершены все потоки, он не реагирует на внешние события. Всё, что у него есть — это информация о том, какой у него был PID, когда он ещё был жив, какой он вернул код возврата при закрытии ну и ещё кое-какие метаданные. Подразумевается, что всё это нужно тому, кто его запускал, он обработает эту информацию за пару секунд после появления «зомби» и «отпустит» его. Но не всё ПО работает так корректно — об этом и статья.
                                                                        • +2
                                                                          собирать статистику и отправлять непосредственно разработчикам.

                                                                          А потом люди жалуются на вездесущую телеметрию.
                                                                        • 0
                                                                          /nubmode on
                                                                          Как этой зомбиловилкой пользоваться? Что скачать надо из этой кучи файлов?
                                                                          Я взял каталог prebuilt — вылетает с ошибкой
                                                                          /nubmode off

                                                                          хмм. скачал всё одним зипом. развернул, запустил — работает. 0 зомби…
                                                                          • 0
                                                                            Скорее всего .exe и .dll нужны. 0 зомби — это круто. Но у большинства так и будет. Ну или будет этих зомбей 5 штук. Это некритично.

                                                                            Проблемы возникают когда в системе заведётся процесс, который их не отпускает и не даёт им умереть спокойно. Тогда можно получить сотни тысяч зомбей и все радости, описанные в статье…
                                                                            • 0
                                                                              у меня Хром ведёт себя не лучше зомби. ну или я себя так веду, открывая стопицот вкладок с ютубом и прочим, и держа их открытыми месяцами
                                                                              • 0
                                                                                Для таких, как вы есть The Great Suspender… хотя почитайте отзывы…
                                                                                • 0
                                                                                  уже снёс его. он спустя неделю вместо ютуба стал показывать ошибку 400 и пришлось удалить его и куки
                                                                          • 0
                                                                            35 total zombie processes.
                                                                            30 zombies held by explorer.exe(5764)
                                                                            28 zombies of LogonUI.exe

                                                                            Причём после каждого Win-L + разблокировки добавляется по одному зомби.

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

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