What is Working Set?
I’m confused with the concept of Working Set ,while reading the Memory Management code of the Windows Research Kernel.
7 Answers 7
The «working set» is short hand for «parts of memory that the current algorithm is using» and is determined by which parts of memory the CPU just happens to access. It is totally automatic to you. If you are processing an array and storing the results in a table, the array and the table are your working set.
This is discussed because the CPU will automatically store accessed memory in cache, close to the processor. The working set is a nice way to describe the memory you want stored. If it is small enough, it can all fit in the cache and your algorithm will run very fast. On the OS level, the kernel has to tell the CPU where to find the physical memory your application is using (resolving virtual addresses) every time you access a new page (typically 4k in size) so also you want to avoid that hit as much as possible.
See What Every Programmer Should Know About Memory — PDF for graphs of algorithm performance vs size of working set (around page 23) and lots of other interesting info.
Basically — write your code to access the smallest amount of memory possible (i.e classes are small, not too many of them), and try to ensure tight loops run on a very very small subset of that memory.
The «working set» is an informal term meaning the memory that’s being accessed «frequently» (for some definition of frequently) by an application or set of applications. Applications may also allocate memory that they access infrequently (no more than once every few dozen seconds, perhaps not even once an hour); this would be outside of the working set.
An example might be if you have two Firefox Windows, a minimized one that you haven’t looked at for several hours, and an open one that you’re browsing in right now. The memory used to store the data associated with the open window is going to be in the working set; the memory used to store the data associated with the window that’s not open and that you haven’t looked at for several hours is not in the working set.
This is mainly used in discussions about whether you have enough RAM in your system. If your working set is smaller than your RAM, you can work comfortably, because the data your program or programs frequently access is always in memory. If your working set is larger than your RAM, the operating system will be constantly swapping pages out to disk to make room to swap in pages that an application wants to access; these swapped out pages, being in the working set, will almost immediately be needed again, meaning that you’ve got to take other pages and write them out to disk, and it just goes on and on like this. This is referred to as «thrashing.»
If you’re not reading or writing many files, your disk light is on all the time, and your system feels very slow, that’s a pretty good sign that you’re thrashing.
Here be dragons: Управление памятью в Windows как оно есть [1/3]
Каталог:
Один
Два
Три
Менеджер памяти (и связанные с ним вопросы контроллера кеша, менеджера ввода/вывода и пр) — одна из вещей, в которой (наряду с медициной и политикой) «разбираются все». Но даже люди «изучившие винду досконально» нет-нет, да и начинают писать чепуху вроде (не говоря уже о другой чепухе, написанной там же):
Цель данной статьи — не полное описание работы менеджера памяти (не хватит ни места ни опыта), а попытка пролить хоть немного света на темное царство мифов и суеверий, окружающих вопросы управления памятью в Windows.
Disclaimer
Сам я не претендую на то, чтобы знать все и никогда не ошибаться, поэтому с радостью приму любые сообщения о неточностях и ошибках.
Введение
С чего начать не знаю, поэтому начну с определений.
Commit Size — количество памяти, которое приложение запросило под собственные нужды.
Working Set (на картинке выше он так и называется Working Set) — это набор страниц физической памяти, которые в данный момент «впечатаны» в адресное пространство процесса. Рабочий набор процесса System принято выделять в отдельный «Системный рабочий набор», хотя механизмы работы с ним практически не отличаются от механизмов работы с рабочими наборами остальных процессов.
И уже здесь зачастую начинается непонимание. Если присмотреться, можно увидеть, что Commit у многих процессов меньше Working Set-а. То есть если понимать буквально, «запрошено» меньше памяти, чем реально используется. Так что уточню, Commit — это виртуальная память, «подкрепленная» (backed) только физической памятью или pagefile-ом, в то время как Working Set содержит еще и страницы из memory mapped файлов. Зачем это делается? Когда делается NtAllocateVirtualMemory (или любые обертки над heap manager-ом, например malloc или new) — память как бы резервируется (чтоб еще больше запутать, это не имеет никакого отношения к MEM_RESERVE, который резервирует адресное пространство, в данном же случае речь идет о резервировании именно физических страниц, которые система действительно может выделить), но физические страницы впечатываются только при фактическом обращении по выделенному адресу виртуальной памяти. Если позволить приложениям выделить больше памяти, чем система реально может предоставить — рано или поздно может случиться так, что все они попросят реальную страницу, а системе неоткуда будет ее взять (вернее некуда будет сохранить данные). Это не касается memory mapped файлов, так как в любой момент система может перечитать/записать нужную страницу прямо с/на диск(а).
В общем, суммарный Commit Charge в любой момент времени не должен превышать системный Commit Limit (грубо, суммарный объем физической памяти и всех pagefile-ов) и с этим связана одна из неверно понимаемых цифр на Task Manager-ах до Висты включительно.
Commit Limit не является неизменным — он может увеличиваться с ростом pagefile-ов. Вообще говоря, можно считать, что pagefile — это такой очень специальный memory mapped файл: привязка физической страницы в виртуальной памяти к конкретному месту в pagefile-е происходит в самый последний момент перед сбросом, в остальном же механизмы memory mapping-а и swapping-а очень схожи.
Working Set процесса делится на Shareable и Private. Shareable — это memory mapped файлы (в том числе и pagefile backed), вернее те части, которые в данный момент действительно представлены в адресном пространстве процесса физической страницей (это же Working Set в конце концов), а Private — это куча, стеки, внутренние структуры данных типа PEB/TEB и т.д. (опять таки, повторюсь на всякий случай: речь идет только той части кучи и прочих структур, которые физически находятся в адресном пространстве процесса). Это тот минимум информации, с которой уже можно что то делать. Для сильных духом есть Process Explorer, который показывает еще больше подробностей (в частности какая часть вот той Shareable действительно Shared).
И, самое главное, ни один из этих параметров по отдельности не позволяет сделать более менее полноценных выводов о происходящем в программе/системе.
Task Manager
Столбец «Memory» в списке процессов и практически вся вкладка «Performance» настолько часто понимаются неправильно, что у меня есть желание, чтоб Task Manager вообще удалили из системы: те, кому надо смогут воспользоваться Process Explorer-ом или хотя бы Resource Monitor-ом, всем остальным Task Manager только вредит. Для начала, собственно о чем речь 

Начну с того, о чем я уже упоминал: Page File usage. XP показывает текущее использование pagefile-а и историю (самое забавное, что в статус баре те же цифры названы правильно), Виста — показывает Page File (в виде дроби Current/Limit), и только Win7 называет его так, чем оно на самом деле является: Commit Charge/Commit Limit.
Эксперимент. Открываем таск менеджер на вкладке с «использованием пейджфайла», открываем PowerShell и копируем в него следующее (для систем, у которых Commit Limit ближе, чем на 3 Гб от Commit Charge можно в последней строчке уменьшить 3Gb, а лучше увеличить pagefile):
Это приводит к мгновенному повышению «использования свопфайла» на 3 гигабайта. Повторная вставка «использует» еще 3 Гб. Закрытие процесса мгновенно освобождает весь «занятый свопфайл». Самое интересное, что, как я уже говорил memory mapped файлы (в том числе и pagefile backed) являются shareable и не относятся к какому либо конкретному процессу, поэтому не учитываются в Commit Size никакого из процессов, с другой стороны pagefile backed секции используют (charged against) commit, потому что именно физическая память или пейджфайл, а не какой нибудь посторонний файл, будут использоваться для того, чтобы хранить данные, которые приложение захочет разместить в этой секции. С третьей стороны, после меппинга секции себе в адресное пространство, процесс не трогает ее — следовательно, физические страницы по этим адресам не впечатываются и никаких изменений в Working Set процесса не происходит.
Строго говоря, пейджфайл действительно «используется» — в нем резервируется место (не конкретное положение, а именно место, как размер), но при этом реальная страница, для которой это место было зарезервировано может находиться в физической памяти, на диске или И ТАМ И ТАМ одновременно. Вот такая вот циферка, признайтесь честно, сколько раз глядя на «Page File usage» в Task Manager-е Вы действительно понимали, что она означает.
Что же до Processes таба — там все еще по дефолту показывается Memory (Private Working Set) и несмотря на то, что он называется совершенно правильно и не должен вызывать недоразумений у знающих людей — проблема в том, что подавляющее большинство людей, которые смотрят на эти цифры совершенно не понимают, что они означают. Простой эксперимент: запускаем утилилиту RamMap (советую скачать весь комплект), запускаете Task Manager со списком процессов. В RamMap выбираете в меню Empty->Empty Working Sets и смотрите на то, что происходит с памятью процессов.
Если кого-то все еще раздражают циферки в Task Manager-е, можете поместить следующий код в профайл павершелла:
После чего станет возможно «оптимизировать» использование памяти одной командой, например для «оптимизации» памяти, занятой хромом: ps chrome | trim
Или вот «оптимизация» памяти всех процессов хрома, использующих больше 100 Мб физической памяти: ps chrome |? <$_.WS -gt 100Mb>| trim
Если хотя бы половина прочитавших отметет саму идею о подобной «оптимизации», как очевиднейший абсурд — можно будет сказать, что я не зря старался.
В первую очередь отмечу, что кеш в Windows не блочный, а файловый. Это дает довольно много преимуществ, начиная от более простого поддержания когерентности кеша например при онлайн дефрагментации и простого механизма очистки кеша при удалении файла и заканчивая более консистентными механизмами его реализации (кеш контроллер реализован на основе механизма memory mapping-а), возможностью более интеллектуальных решений на основе более высокоуровневой информации о читаемых данных (к примеру интеллектуальный read-ahead для файлов открытых на последовательный доступ или возможность назначать приоритеты отдельным файловым хендлам).
В принципе из недостатков я могу назвать только значительно более сложную жизнь разработчиков файловых систем: слышали о том, что написание драйверов — это для психов? Так вот, написание драйверов файловых систем — для тех, кого даже психи считают психами.
Если же описывать работу кеша, то все предельно просто: когда файловая система запрашивает у кеш-менеджера какую нибудь часть файла, последний просто меппит часть этого файла в специальный «слот», описываемый структурой VACB (посмотреть все смепленные файлы можно из отладчика ядра с помощью расширения !filecache) после чего просто выполняет операцию копирования памяти (RtlCopyMemory). Происходт Page Fault, так как сразу после отображения файла в память все страницы невалидны и дальше система может либо найти необходимую страницу в одном из «свободных» списков либо выполнить операцию чтения.
Для того, чтобы понять рекурсию нужно понять рекурсию. Каким же образом выполняется операция чтения файла, необходимая для завершения операции чтения этого самого файла? Здесь опять все достаточно просто: пакет запроса на ввод/вывод (IRP) создается с флагом IRP_PAGING_IO и при получении такого пакета файловая система уже не обращается к кешу, а идет непосредственно к нижележащему дисковому устройству за данными. Все эти смепленные слоты идут в System Working Set и составляют ЧАСТЬ кеша.
Страница из лекции какого то токийского университета (эх, мне бы так): 
На этом работа собственно кеш-менеджера заканчивается и начинается работа менедера памяти. Когда выше мы делали EmptyWorkingSet это не приводило ни к какой дисковой активности, но тем не менее, физическая память используемая процессом сокращалась (и все физические страницы действительно уходили из адресного пространства процесса делая его почти полностью невалидным). Так куда же она уходит после того, как отбирается у процесса? А уходит она, в зависимости от того, соответствует ли ее содержимое тому, что было прочитано с диска, в один из двух списков: Standby (начиная с Висты это не один список, а 8, о чем позже) или Modified:
Standby список таким образом — это свободная память, содержащая какие то данные с диска (в том числе возможно и pagefile-а).
Если Page Fault происходит по адресу, который спроецирован на часть файла, которая все еще есть в одном из этих списков — она просто возвращается обратно в рабочий набор процесса и впечатывается по искомому адресу (этот процесс называется softfault). Если нет — то, как и в случае со слотами кеш менеджера, выполняется PAGING_IO запрос (называется hardfault).
Modified список может содержать «грязные» страницы достаточно долго, но либо когда размер этого списка чрезмерно вырастает, либо по когда система видит недостаток свободной памяти, либо по таймеру, просыпается modified page writer thread и начинает частями сбрасывать этот список на диск, и перемещая страницы из modified списка в standby (ведь эти страницы опять содержат неизмененную копию данных с диска).
Upd:
Пользователь m17 дал ссылки на выступление Руссиновича на последнем PDC на ту же тему (хм, я честно его до этого не смотрел, хотя пост во много перекликается). Если понимание английского на слух позволяет, то чтение данного топика можно заменить прослушиванием презентаций:
Mysteries of Windows Memory Management Revealed, Part 1 of 2
Mysteries of Windows Memory Management Revealed, Part 2 of 2
Пользователь DmitryKoterov подсказывает, что перенос пейджфайла на RAM диск иногда действительно может иметь смысл (вот уж никогда б наверное и не догадался, если б не написал топик), а именно, если RAM-диск использует физическую память, недоступную остальной системе (PAE + x86 + 4+Gb RAM).
Пользователь Vir2o в свою очередь подсказывает что хотя при некоторых условиях и пожертвовав стабильностью системы ram-диск, использующий физическую память, невидимую остальной системе написать можно, но такое очень маловероятно.
Что такое Режим ожидания на смартфоне Samsung?

Одной из самых важных задач, которую решает Искусственный Интеллект (ИИ) Операционной Системы смартфона — это оптимизация работы всех систем телефона, чтобы увеличить автономность работы смартфона, то есть время его работы без подзарядки аккумулятора.
Причин, которые влияют на повышенный расход заряда батареи очень много, и часть из них мы уже освещали в статье «7 причин медленной зарядки смартфона Samsung». Для перехода к ней нажмите здесь.
Самые главные «потребители» заряда аккумулятора — это экран смартфона и чипсе́т (с англ. chipset — набор микросхем, обеспечивающих совместную работу всей системы). И самым важным фактором в работе чипсета является загрузка его Центрального Процессора (ЦП) количеством одновременно запущенных приложений. Сами приложения смартфона могут быть как в активном состоянии, так и работающие в фоновом режиме.
Активные приложения мы не можем отключить, так как они в работе, а вот с фоновыми приложениями с целью оптимизации расхода энергии батареи нужно разобраться. И эту задачу производители смартфонов с ОС Android передали Искусственному Интеллекту (ИИ) телефона.
А как организовано управление фоновых процессов с целью экономии заряда батареи на смартфонах Samsung?
Для этого на смартфонах Samsung существует специальный режим «Адаптивный режим аккумулятора», который, как правило, включен по умолчанию. В этом режиме ИИ вашего телефона не позволяет приложениям разряжать батарею, пока они не запущены, что может сэкономить значительное время автономной работы вашего устройства.
Для этого Искусственный Интеллект (ИИ) вначале исследует, как часто вы используете все приложения на своем смартфоне. И в дальнейшем ИИ уже использует эту информацию, чтобы определить для каждого приложения один из пяти так называемых «СТАТУСОВ режима ожидания»:
— EXEMPTED (по-русски – СВОБОДНЫЙ);
— ACTIVE (по-русски — АКТИВНЫЙ);
— WORKING_SET (по-русски — РАБОЧИЙ);
— FREQUENT (по-русски — ЧАСТО);
— RARE (по-русски — РЕДКО).
Режим ожидания — это режим работающего смартфона, который в этот момент времени не используется, то есть когда телефон включен, но его экран выключен. Именно в этом режиме достигается наибольшая экономия энергии заряда батареи.
Статус «Exempted» назначают, как правило, системным приложениям, которые не подлежат отключению.
Статус «Active» предаётся самым активным приложениям, которые вы используете в данный момент, или те, которые прямо сейчас выполняют какие-то процессы в фоне (например, загрузка файла).
Статус «Working_Set» определяется для тех приложений, которые вы часто используете, но не используете в данный момент.
Статус «Frequent» предаётся приложениям, которые вы используете регулярно, но не каждый день.
И наконец, статус «Rare» предназначен для тех приложений, которые вы используете очень редко.
Каждый из этих статусов связан с набором правил экономии заряда аккумулятора, налагаемых ОС Android. По мере того, как приложения переходят от статуса «Active» к «Rare», эти правила становятся более строгими. Например, приложения «Active» не имеют ограничений по использованию заряда батареи, в то время как приложения «Rare» имеют самый низкий приоритет, и им будут отдаваться минимум ресурсов.
А как включить «Адаптивный режим аккумулятора» и для отдельных приложений изменить «статус в режиме ожидания» на смартфоне Samsung?
Далее мы опишем порядок включения «Адаптивный режим аккумулятора» на смартфонах Самсунг Галакси и изменения статуса для отдельных приложений на примере редакционного смартфона Samsung Galaxy A50 под ОС Android 10 с фирменной оболочкой One UI 2.0.
Важное замечание: В случае выключения режима «Адаптивный режим аккумулятора» все приложения получат одинаковый статус энергосбережения — ACTIVE, что повлечёт менее экономный режим эксплуатации телефона.
Инструкция по включению «Адаптивного режима аккумулятора» на смартфоне Samsung
1. Запускаем приложение Настройки телефона с экрана приложений.
alt=»Статус ожидания 1″ width=»330″ height=»712″ />Скрин №1 – нажать на значок «Настройки».
2. На основной странице Настроек телефона нужно войти в раздел «Обслуживание устройства».
alt=»Статус ожидания 2″ width=»330″ height=»712″ />Скрин №2 – нажать на раздел «Обслуживание устройства».
3. В разделе «Обслуживание устройства» нужно нажать на строчку «Батарея».
alt=»Статус ожидания 3″ width=»330″ height=»712″ />Скрин №3 – нажать на строчку «Батарея».
4. В подразделе «Батарея» нужно войти в подраздел «Мониторинг энергопотребления приложений».
alt=»Статус ожидания 4″ width=»330″ height=»712″ />Скрин №4 – активировать подраздел «Мониторинг энергопотребления приложений».
5. Теперь, находясь в подразделе «Мониторинг энергопотребления приложений», нужно включить службу «Адаптивный режим аккумулятора» нажатием на переключатель одноимённого пункта.
alt=»Статус ожидания 5″ width=»330″ height=»712″ />Скрин №5 – нажать на переключатель пункта «Адаптивный режим аккумулятора».
Теперь на нашем смартфоне включена функция «Адаптивный режим аккумулятора», которая передала управление оптимальным расходом заряда батареи Искусственному Интеллекту смартфона.
Вид раздела «Мониторинг энергопотребления приложений» смартфона с подключенной службой «Адаптивный режим аккумулятора».
alt=»Статус ожидания 6″ width=»330″ height=»712″ />Скрин №6 – вид раздела «Мониторинг энергопотребления приложений».
Инструкция по изменению статуса приложений в режиме ожидания на смартфоне Samsung
Для отдельных приложений Вы можете изменить статус в режиме ожидания, когда считаете необходимым временное выключение какого-то приложения с целью экономии заряда батареи или наоборот — его постоянную работу. Режим ожидания – это тот момент времени, когда смартфон активно не используется, то есть когда он включен, но его экран выключен. Именно в этом положении большую часть времени находятся большинство смартфонов.
Изменения статуса приложений в режиме ожидания осуществляется в специальном разделе Настроек телефона — «Параметры разработчика». Порядок подключения этого раздела описан в статье «Как включить режим разработчика на смартфоне Samsung.». Для перехода к ней нажмите здесь.
Если у Вас раздел «Параметры разработчика» уже активирован, тогда мы можем перейти к описанию изменения статуса приложений в режиме ожидания.
1. Запускаем приложение Настройки телефона с экрана приложений.
alt=»Статус ожидания 7″ width=»330″ height=»712″ />Скрин №7 – нажать на значок «Настройки».
2. На основной странице Настроек телефона нужно войти в раздел «Параметры разработчика».
alt=»Статус ожидания 8″ width=»330″ height=»712″ />Скрин №8 – нажать на раздел «Параметры разработчика».
3. Находясь в разделе «Параметры разработчика» нам нужно найти пункт «Приложения в режиме ожидания». Это можно сделать, листая довольно внушительный список пунктов этого раздела, или через режим поиска перейти к нему сразу.
Мы решили перейти к нему через систему поиска.
Для этого вначале нужно нажать на значок «Поиск» вверху экрана.
alt=»Статус ожидания 9″ width=»330″ height=»712″ />Скрин №9 — активировать режим поиска. Для этого нажать на значок «Поиск».
Далее в строке поиска нужно набрать ключевое слово «ожидания».
После этого система сразу произведет поиск всех возможных вариантов содержащих слово «ожидания» и сформирует список «найденного».
Первый пункт списка отвечает нашему запросу — «Приложения в режиме ожидания». Поэтому нажимаем на эту строчку из списка найденного.
alt=»Статус ожидания 10″ width=»330″ height=»712″ />Скрин №10 – в строе поиска набрать слово «ожидания». А после в списке найденных вариантов поиска нажать на строчку «Приложения в режиме ожидания».
4. Теперь в разделе «Параметры разработчика» нужно войти в найденный подраздел «Приложения в режиме ожидания».
alt=»Статус ожидания 11″ width=»330″ height=»712″ />Скрин №11 – войти в подраздел «Приложения в режиме ожидания».
5. Подраздел «Приложения в режиме ожидания» представляет собой список всех приложений, установленных на смартфоне, с указанием статуса приложения в режиме ожидания.
Мы решили изменить статус для приложения «2ГИС» с «ACTIVE» (активный) на «RARE» (редко). Для этого нужно нажать на строчку приложения «2ГИС».
alt=»Статус ожидания 12″ width=»330″ height=»712″ />Скрин №12 – нажать на строчку приложения «2ГИС».
После этого откроется окошко. Для смены статуса нужно нажать на строчку «RARE».
alt=»Статус ожидания 13″ width=»330″ height=»712″ />Скрин №13 – в окошке для смены статуса нажать на строчку «RARE».
6. Теперь у нас приложение «2ГИС» поменяла свой статус на «RARE». И в режиме ожидания это приложение с целью экономии заряда батареи будет временно отключаться.
Вид подраздела «Приложения в режиме ожидания» с изменённым статусом для «2ГИС».
alt=»Статус ожидания 14″ width=»330″ height=»712″ />Скрин №14 — вид подраздела «Приложения в режиме ожидания», где приложение «2ГИС» со статусом «RARE» (редко).