Это на самом деле довольно просто, если вы понимаете, что плата за коммит представляет собой только потенциальное - но «гарантированно доступное, если вы этого хотите» - использование виртуальной памяти, тогда как "частный рабочий набор", который по сути является ОЗУ, используемым "выделенной" памятью фактическое использование, так же как пространство файла подкачки. (Но это не все использование ОЗУ, потому что есть другие вещи, которые используют ОЗУ).
Предположим, мы говорим о 32-битных системах, поэтому максимальное виртуальное адресное пространство, доступное каждому процессу, обычно составляет 2 ГиБ. (Для 64-битных систем нет существенного различия ни в одном из следующих пунктов, за исключением того, что адреса и размеры могут быть больше - намного больше.)
Теперь предположим, что программа, запущенная в процессе, использует VirtualAlloc (Win32 API) для "фиксации" 2 МБ виртуальной памяти. Как и следовало ожидать, это будет отображаться как дополнительные 2 МБ фиксации, и в процессе будет доступно на 2 МБ меньше виртуального адресного пространства для будущих выделений.
Но он пока не будет использовать физическую память (RAM)!
Вызов VirtualAlloc вернет вызывающему абоненту начальный адрес выделенной области; область будет где-то в диапазоне от 0x10000 до 0x7FFEFFFF, то есть около 2 ГиБ. (Первый и последний 64 КБ или 0x10000 в шестнадцатеричном виде vas в каждом процессе никогда не назначаются.)
Но опять же - пока нет фактического физического использования 2 МБ хранилища ! Не в оперативной памяти, даже в файле подкачки. (Существует крошечная структура, называемая "дескриптор виртуального адреса", которая описывает начальное значение va и длину частного зафиксированного региона.)
Так что у вас есть это! Зафиксированный заряд увеличился, а использование физической памяти - нет.
Это легко продемонстрировать с помощью testlimit
инструмента sysinternals .
Некоторое время спустя, скажем, программа хранит что-то (то есть операцию записи в память) в этом регионе (не имеет значения, где). Под каким-либо регионом еще нет физической памяти, поэтому такой доступ приведет к ошибке страницы. В ответ на это диспетчер памяти ОС, в частности подпрограмма обработки ошибок страниц (для краткости "пейджер"… это называется MiAccessFault), будет:
- выделить ранее "доступную" физическую страницу
- настроить запись таблицы страниц для виртуальной страницы, к которой был получен доступ, чтобы связать номер виртуальной страницы с вновь назначенным номером физической страницы
- добавить физическую страницу в приватный рабочий набор процесса
- и отклонить ошибку страницы, вызвав повторную попытку инструкции, которая вызвала ошибку.
Теперь вы "винили" одну страницу (4 КиБ) в процессе. И использование физической памяти будет соответственно увеличиваться, а "доступная" оперативная память будет уменьшаться. Фиксация заряда не меняется.
Некоторое время спустя, если на эту страницу некоторое время не ссылались и спрос на оперативную память высок, это может произойти:
- ОС удаляет страницу из рабочего набора процесса.
- поскольку он был записан, так как он был внесен в рабочий набор, он помещается в измененный список страниц (в противном случае он попадет в список резервных страниц). Запись таблицы страниц по-прежнему отражает физический номер страницы страницы оперативной памяти, но теперь ее бит "valid" очищен, поэтому при следующей ссылке на нее произойдет сбой страницы.
- когда измененный список страниц достигает небольшого порога, измененный поток средства записи страниц в процессе "Система" просыпается и сохраняет содержимое измененных страниц в файл подкачки (при условии, что он у вас есть), и ...
- удаляет эти страницы из измененного списка и помещает их в резервный список. Теперь они считаются частью "доступной" оперативной памяти; но на данный момент они все еще имеют свое первоначальное содержание от того, когда они были в своих соответствующих процессах. Опять же, плата за фиксацию не меняется, но использование оперативной памяти и частного рабочего набора процесса снижается.
- Страницы в резервном списке теперь могут быть переназначены, то есть использованы для чего-то другого - например, для устранения ошибок страниц в любом процессе в системе или для использования SuperFetch. Тем не мение...
- Если процесс, потерявший страницу в измененном или резервном списке, попытается снова получить к ней доступ до того, как физическая страница будет переназначена (т. Е. Все еще имеет свое первоначальное содержимое), ошибка страницы устраняется без чтения с диска. Страница просто возвращается в рабочий набор процесса, и запись в таблице страниц становится "действительной". Это пример "мягкой" или "дешевой" ошибки страницы. Мы говорим, что резервные и модифицированные списки образуют общесистемный кеш страниц, которые, скорее всего, скоро понадобятся снова.
Если у вас нет файла подкачки, то шаги с 3 по 5 изменяются на:
Страницы находятся в измененном списке, так как их содержимое некуда писать.
Страницы находятся в измененном списке, так как их содержимое некуда писать.
Страницы находятся в измененном списке, так как их содержимое некуда писать.
Шаг 6 остается тем же, так как страницы в измененном списке могут быть возвращены в процесс, который потерял их как "мягкую" ошибку страницы. Но если этого не произойдет, страницы будут находиться в измененном списке до тех пор, пока процесс не освободит соответствующую виртуальную память (возможно, потому что процесс завершается).
Существует и другое использование виртуального адресного пространства и оперативной памяти, помимо частной выделенной памяти. Существует сопоставленное виртуальное адресное пространство, для которого резервным хранилищем является некоторый указанный файл, а не файл подкачки. Страницы отображенных vas, которые перемещаются по страницам, отражаются в использовании ОЗУ, но отображенная память не вносит свой вклад в фиксацию, потому что отображенный файл обеспечивает резервное хранилище: любая часть отображаемой области, которая не находится в ОЗУ, просто сохраняется в сопоставленный файл. Другое отличие состоит в том, что большинство отображений файлов могут быть разделены между процессами; разделяемая страница, которая уже находится в памяти для одного процесса, может быть добавлена к другому процессу без повторного перехода на диск (еще одна ошибка программной страницы).
И есть нестраиваемый vas, для которого нет резервного хранилища, потому что он всегда находится в оперативной памяти. Это способствует как сообщаемому использованию оперативной памяти, так и "фиксации заряда".
Это, кажется, может быть из-за сжатия. Что превращает вопрос в: почему лимит коммитов не повышается или что-то еще? Т.е. какой смысл сжимать, если это не помогает с использованием памяти?
Нет, это не имеет никакого отношения к сжатию. Сжатие памяти в Windows выполняется как промежуточный шаг на страницах, которые в противном случае были бы записаны в файл подкачки. По сути, он позволяет модифицированному списку страниц использовать меньше оперативной памяти, чтобы содержать больше информации, при некоторой стоимости процессорного времени, но с гораздо большей скоростью, чем ввод / вывод из файла подкачки (даже для SSD). Поскольку лимит коммитов рассчитывается из общего объема ОЗУ + размера файла подкачки, а не использования ОЗУ + использования файла подкачки, это не влияет на лимит фиксации. Предел фиксации не зависит от того, сколько ОЗУ используется или для чего оно используется.
Когда коммитный заряд заполняется, и окна начинают просить меня закрыть вещи, большую часть времени физическая память находится на уровне около 60%. Это кажется ужасно неэффективным.
Дело не в том, что Windows неэффективна. Это приложения, которые вы запускаете. Они выделяют гораздо больше ВАС, чем используют.
Причина всего механизма "фиксации заряда" и "предела фиксации" заключается в следующем: когда я вызываю VirtualAlloc, я должен проверить возвращаемое значение, чтобы убедиться, что оно ненулевое. Если он равен нулю, это означает, что моя попытка размещения не удалась, вероятно, потому что это привело бы к тому, что заряд фиксации превысил предел фиксации. Я должен сделать что-то разумное, например, попробовать совершить меньше или выйти из программы чисто.
Если VirtualAlloc вернул ненулевое значение, т. Е. Адрес, который говорит мне, что система дала гарантию (если хотите, обязательство), что все те байты, которые я запросил, начиная с этого адреса, будут доступны, если я решу получить к ним доступ; что есть куда поместить все это - либо RAM, либо файл подкачки. то есть нет никаких оснований ожидать какого-либо сбоя в доступе к чему-либо в этом регионе. Это хорошо, потому что было бы неразумно ожидать, чтобы я проверил, "работает ли это?"«при каждом доступе к выделенному региону.
Аналогия с "банком кредитования наличными"
Это немного походит на банк, предлагающий кредит, но строго на наличной основе. (Это, конечно, не так, как работают настоящие банки.)
Предположим, что банк начинается с наличных денег на миллион долларов. Люди идут в банк и просят кредитные линии на разные суммы. Скажем, банк одобряет меня на кредитную линию в 100 000 долларов (я создаю частный выделенный регион); это не означает, что наличные деньги действительно покинули хранилище. Если позже я действительно возьму кредит, скажем, на 20 000 долларов (я получаю доступ к подмножеству региона), это действительно снимает наличные с банка.
Но независимо от того, беру я кредиты или нет, тот факт, что я был утвержден на максимальную сумму в 100 000 долларов США, означает, что банк впоследствии может одобрить только еще одну кредитную линию на общую сумму 900 000 долларов США для всех своих клиентов. Банк не утвердит кредит сверх своих денежных резервов (т. Е. Он не будет превышать их), поскольку это может означать, что банку, возможно, придется отказать ранее утвержденному заемщику, когда они позже появятся, намереваясь взять свой кредит , Это было бы очень плохо, потому что банк уже взял на себя обязательство предоставлять эти кредиты, и репутация банка резко упала бы.
Да, это "неэффективно" с точки зрения использования банком этих денежных средств. И чем больше различие между кредитными линиями, на которые утверждаются клиенты, и суммами, которые они фактически ссужают, тем менее эффективными они являются. Но эта неэффективность не вина банка; "вина" клиентов заключается в том, что они просят такие высокие кредитные линии, но берут только небольшие кредиты.
Бизнес-модель банка заключается в том, что он просто не может отказаться от ранее одобренного заемщика, когда они появляются, чтобы получить кредит - это будет "фатальным" для клиента. Вот почему банк внимательно следит за тем, сколько из заемного фонда было "выделено".
Я полагаю, что расширение файла подкачки или добавление еще одного файла было бы похоже на то, как банк выходит и получает больше денег и добавляет его в заемный фонд.
Если вы хотите смоделировать сопоставленную и нестраиваемую память по этой аналогии ... nonpageable - это небольшой заем, который вы должны взять и не допускать при открытии своего аккаунта. (Не допускаемые страницы структуры, которые определяют каждый новый процесс.) Отображаемая память - это то же самое, что взять с собой ваши собственные деньги (файл, который сопоставляется) и поместить их в банк, а затем вынимать только отдельные части за раз (разбирать на страницы). Почему бы не заняться этим сразу? Я не знаю, может быть, у вас нет места в вашем кошельке для всех этих денег. :) Это не влияет на способность других лиц занимать деньги, потому что внесенные вами деньги находятся на вашем собственном счете, а не в общем кредитном фонде. Эта аналогия начинает рушиться, особенно когда мы начинаем думать о разделяемой памяти, так что не вдавайтесь слишком далеко.
Вернемся к ОС Windows: тот факт, что у вас имеется большая часть "доступной" оперативной памяти, не имеет ничего общего с начислением и ограничением. Если вы приближаетесь к пределу фиксации, это означает, что ОС уже зафиксировала - то есть пообещала сделать доступным по запросу - столько памяти. Это не должно быть все в использовании еще для того, чтобы предел был применен.
Могу ли я отказаться от искусственного раздувания файла подкачки до уровней, на которых мой истощенный для пространства твердотельный накопитель плохо приспособлен для того, чтобы я мог эффективно использовать свою физическую память? (Или даже если это было не так полно. То есть я хотел бы избежать предложений типа «Сделайте X/Y/Z для вашего файла подкачки».)
Что ж, извините, но если вы работаете в пределе коммитов, вы можете сделать только три вещи:
- Увеличьте свою оперативную память.
- Увеличьте размер вашего файла подкачки.
- Запустите меньше вещей за один раз.
По варианту 2: Вы можете поместить второй файл подкачки на жесткий диск. Если приложения на самом деле не используют всю эту выделенную память - а это, по-видимому, не так, поскольку вы видите так много свободной оперативной памяти - вы на самом деле не будете часто обращаться к этому файлу страниц, поэтому его установка на жесткий диск не повредить производительность. Если медлительность жесткого диска все еще беспокоит вас, другой вариант - это получить маленький и, следовательно, дешевый второй SSD и поместить туда второй файл подкачки. Один "showtopper" будет ноутбуком без возможности добавить второй "несъемный" диск. (Windows не позволяет размещать файлы подкачки на съемных дисках, как и все, что связано с USB.)
Вот еще один ответ, который я написал, который объясняет вещи с другой стороны.
ps: Вы спрашивали о Windows 10, но я должен сказать вам, что она работает одинаково в каждой версии семейства NT, начиная с NT 3.1, и предварительных версий. Вероятно, изменилось значение Windows по умолчанию для размера файла подкачки, от 1,5 или 1x объема ОЗУ до гораздо меньшего размера. Я считаю, что это было ошибкой.