
Эта системная информация из Process Explorer. Физическая память все еще доступна, но система показывает, что ОЗУ почти не осталось.
Диспетчер задач также показывает, что используется около 74% общего объема оперативной памяти.
После установки Windows 8.1 на компьютере было 4+8=12 ГБ оперативной памяти. Я обновил ее, заменив 4 ГБ на 8 ГБ модуль. Может ли это быть проблемой? Или это нормальное поведение, и я просто неправильно понял значение доступной физической памяти?
решение1
Короткий ответ
Всплывающее окно «недостаточно памяти» говорит о том, что ваш лимит начастный преданный делупамять — тип виртуальной памяти. Не то, чтобы у вас заканчивалась оперативная память (физическая память). Неважно, сколькодоступныйRAM у вас есть. Наличие большого количества доступной RAM не позволяет вам превысить лимит фиксаций. Лимит фиксаций — это сумма ваших общийОперативная память (используется она или нет!) плюс текущий размер файла подкачки.
И наоборот, то, что "использует" лимит коммита (что в основном является созданием виртуального адресного пространства, приватного для процесса), не обязательно использует оперативную память! Но ОС не позволит его создать, если не будет знать, что есть место для его хранения, если когда-нибудь понадобится. Так что вы можете упереться в лимит коммита, не используя всю оперативную память или даже большую ее часть.
Вот почему вам не следует запускать без файла подкачки. Обратите внимание, что файл подкачки может вообще не быть записан! Но это все равно позволит вам избежать ошибок "low on memory" и "out of memory".
Промежуточный ответ
В Windows на самом деле нет сообщения об ошибке исчерпания оперативной памяти. То, что у вас исчерпывается, это "предел фиксации".
Граф "System" в этой версии Process Explorer назван неудачно. Он должен быть назван "commit charge". (В моей версии он называется "System commit". Лучше, но все еще не совсем согласованно.) В любом случае "текущая" высота графика - это то, что показано ниже в текстовом разделе как "Commit Charge" - "Current", а максимальная высота графика представляет "Commit Charge" - "Limit".
«Commit charge» относится к виртуальному адресному пространству, которое поддерживается файлом подкачки (если он у вас есть) — другими словами, если все не помещается в ОЗУ, остаток помещается в файл подкачки. (Существуют и другие типы vas, которые либо поддерживаются другими файлами — это называется «отображенными» vas — или должны все время оставаться в ОЗУ; последний называется «невыгружаемым».) «Commit limit» — это максимально допустимый «commit charge». Он равен размеру вашей ОЗУ плюс размер файла подкачки.
Судя по всему, у вас нет файла подкачки (я это знаю, потому что ваш лимит на передачу данных равен размеру оперативной памяти), поэтому лимит на передачу данных — это просто размер оперативной памяти.
Видимо, различные программы и ОС использовали почти весь максимально возможный объем памяти.
Это не имеет прямого отношения к тому, сколько оперативной памяти свободно или доступно. Да, у вас есть около 4,5 ГБ оперативной памяти. Это не значит, что вы можете превысить лимит выделения. Выделенная память не обязательно использует оперативную память и не ограничена объемом доступной оперативной памяти.
Вам нужно либо снова включить файл подкачки (используя так много выделенных ресурсов, я бы предложил файл подкачки на 16 ГБ, потому что вы не хотите заставлять ОС хранить так много всего в оперативной памяти, а файл подкачки работает лучше всего, если в нем много свободного места), либо добавить больше оперативной памяти. НАМНОГО больше. Для хорошей производительности вам нужно иметь много места в оперативной памяти для кода и других вещей, которые не поддерживаются файлом подкачки (но могут быть выгружены в другие файлы).
Очень длинный ответ
(но все равно намного короче, чем глава об управлении памятьюВнутреннее устройство Windows...)
Предположим, что программа выделяет 100 МБ виртуальной памяти, приватной для процесса. Это делается с помощью вызова VirtualAlloc с опцией "commit". Это приведет к увеличению "Commit charge" на 100 МБ. Но это "выделение" на самом деле не использует никакой оперативной памяти! Оперативная память используется только тогда, когда часть этой недавно выделеннойвиртуальное адресное пространстводоступ осуществляется впервые.
Как в конечном итоге используется оперативная память
(если это когда-нибудь произойдет)
Первый доступ к недавно выделенному пространству почти всегда будет записью в память (чтение недавно выделенного частного vas перед записью в него почти всегда является ошибкой программирования, поскольку его начальное содержимое, строго говоря, не определено). Но чтение или запись, результат, когда вы впервые касаетесь страницы недавно выделенного vas, являетсяошибка страницы. Хотя слово «сбой» звучит неприятно, сбои страниц — это вполне ожидаемое и даже необходимое событие в ОС виртуальной памяти.
В ответ на этот конкретный тип ошибки страницы пейджер (часть диспетчера памяти ОС, который я иногда буду сокращать до «ММ») выполняет следующие действия:
- выделить физическую страницу оперативной памяти (в идеале из списка нулевых страниц, но в любом случае она берется из того, что Windows называет «доступными»: нулевой, свободный или резервный список страниц в указанном порядке предпочтения);
- заполнитезапись таблицы страницсвязать физическую страницу с виртуальной страницей; и наконец
- отклонить исключение ошибки страницы.
После этого код, выполнивший обращение к памяти, повторно выполнит инструкцию, вызвавшую ошибку страницы, и на этот раз обращение будет успешным.
Мы говорим, что страница была «заброшена» в рабочий набор процесса и в оперативную память. В диспетчере задач это будет выглядеть как увеличение на одну страницу (4 КБ) в «частном рабочем наборе» процесса. И уменьшение на одну страницу в доступной физической памяти. (Последнее может быть трудно заметить на загруженной машине.)
Примечание 1:Эта ошибка страницы не включала в себя что-либо, прочитанное с диска. Никогда ранее не использовавшаяся страница выделенной виртуальной памяти не начинает жизнь на диске; у нее нет места на диске, чтобы ее прочитатьот. Он просто «материализуется» в ранее доступной странице ОЗУ. Фактически, по статистике, большинство ошибок страниц разрешаются в ОЗУ, либо в общих страницах, которые уже находятся в ОЗУ для других процессов, либо в кэшах страниц — резервных или измененных списках, или как страницы «нулевого спроса», такие как эта.
Заметка 2:Это занимает всего одну страницу, 4096 байт, из «Доступно». Никогда не тронуто-раньше зафиксированное адресное пространство обычно реализуется — сбойно — только по одной странице за раз, поскольку каждая страница «трогается» в первый раз. Не было бы никакого улучшения, никакого преимущества, если бы мы делали больше за раз; это просто заняло бы в n раз больше времени. Напротив, когда страницы должны быть прочитаны с диска, предпринимается попытка некоторого количества «упреждающего чтения», поскольку подавляющее большинство времени при чтении с диска уходит на накладные расходы на каждую операцию, а не на фактическую передачу данных. «Зафиксированный» объем остается на уровне 100 МБ; тот факт, что одна или несколько страниц были сбоем, не снижает плату за фиксацию.
Заметка 3:Предположим, что у нас есть 4 ГБ «доступной» оперативной памяти. Это означает, что мы могли бы ссылаться на уже выделенную, но никогда ранее не использованную выделенную память еще около миллиона раз (4 ГБ / 4096), прежде чем у нас закончится оперативная память. В этот момент, если у нас есть файл подкачки, как предполагали Дэвид Катлер и Лу Пераццоли, некоторые из самых давно использованных страниц в оперативной памяти будут сохранены на диске, а затем станут доступными для использования при устранении этих более поздних ошибок страниц. (На самом деле ОС инициирует методы высвобождения оперативной памяти, такие как «обрезка рабочего набора», а не до этого, и фактические записи в файл подкачки кэшируются и группируются в измененном списке страниц для эффективности, и и...) Ничто из этого не повлияет на количество «выделенных». Однако это имеет отношение к «лимиту выделенных». Если в оперативной памяти нет места для всей «выделенной» памяти, избыток можно сохранить в файле подкачки. Таким образом, размер файла подкачки влияет на «лимит фиксации».
И это продолжается...
Но предположим, что мы не сделали еще миллион ссылок и все еще есть около 4 ГБ страниц "доступных". Теперь предположим, что тот же процесс - или другой, неважно - делает еще один VirtualAlloc, на этот раз, скажем, 200 МБ выделенных. Опять же, эти 200 МБ добавляются к стоимости выделенных, и это не удаляет никакой оперативной памяти из доступной. Простое виртуальное адресное пространство не использует соответствующий объем оперативной памяти, и низкий уровень "доступной" оперативной памяти не ограничивает объем адресного пространства, который вы можете VirtualAlloc (и высокий уровень доступной оперативной памяти не увеличивает его).
(Ну ладно... есть небольшие накладные расходы, составляющие одну (выгружаемую на страницы!) страницу, которая используется для таблицы страниц на каждые 2 МБ (4 МБ, если вы работаете в системе x86, не-PAE) выделенного виртуального адресного пространства, и есть «дескриптор виртуального адреса» размером в несколько десятков байт для каждого виртуально непрерывного выделенного диапазона.)
Таким образом, возможно — и это часто случается! — израсходовать много «запаса памяти», используя при этом лишь небольшие объемы оперативной памяти.
Итак, если «выделение» виртуального адресного пространства не использует оперативную память, почему должен быть предел?
Поскольку «обязательная плата» действительно представляет собой потенциалбудущееиспользование дискового пространства. «Лимит выделения» представляет собой общий объем дискового пространства (ОЗУ + пространство файла подкачки), доступного для хранения таких выделений,если на них когда-либо будут ссылаться, и тогда их нужно будет где-то хранить.
Когда Mm одобряет запрос VirtualAlloc, он обещает - "берет на себя обязательство" - что все последующие доступы к памяти в выделенной области будут успешными; они могут привести к ошибкам страниц, но все ошибки будут устранены, поскольку ЕСТЬ достаточно места для хранения содержимого всех этих страниц, будь то в ОЗУ или в файле подкачки. Mm знает это, потому что знает, сколько места для хранения есть (лимит фиксации) и сколько уже было "фиксировано" (текущая плата за фиксацию).
(Но не все эти страницы еще не были просмотрены, поэтому не обязательно существует реальный объем хранилища, соответствующий выделенному объему в любой момент времени.)
Итак... А как насчет «системе не хватает памяти»?
Если вы попытаетесь использовать VirtualAlloc, а текущая стоимость фиксации плюс запрошенный размер выделения выведут вас за пределы лимита фиксации, И ОС не сможет расширить файл подкачки, чтобы увеличить лимит фиксации... вы получите всплывающее окно «недостаточно памяти», и процесс увидит, что вызов VirtualAlloc НЕУДАЧЕН. Большинство программ просто опустят руки и умрут в этот момент. Некоторые будут слепо продолжать, предполагая, что вызов прошел успешно, и потерпят неудачу позже, когда попытаются сослаться на область, которую, как они думали, они выделили.
Опять же (извините за повтор): неважно, сколько у вас есть доступной оперативной памяти. ОС обещала, что оперативная память или пространство файла подкачкиволябыть доступным, когда это необходимо, но это обещание не вычитается из "Доступно". Доступная оперативная память используется только выделенной виртуальной машиной, когда онассылаетсявпервые, что и приводит к тому, что он "faulted in"... т.е. реализуется в физической памяти. И простое выделение (= выделение) виртуальной памяти не делает этого. Он только берет свободное виртуальное адресное пространство и делает из него пригодное для использования виртуальное адресное пространство.
Но в случае «нехватки памяти» был запрос на выделение выделенной памяти, и ОС добавила текущую стоимость выделения к размеру этого нового запроса... и обнаружила, что общая сумма составляетболеечем предел фиксации. Так что если ОС одобрила этот новый,ипосле этого все это пространство было использовано, не осталось бы никаких реальных мест (ОЗУ + файл подкачки) для хранения всего этого.
ОС этого не допустит. Она не позволит выделить больше vas, чем у нее есть места для хранения в худшем случае - даже если все это "завалится". В этом и заключается цель "лимита фиксации".
Я говорю тебе трижды, я говорю тебе трижды, я говорю тебе трижды:Объем «доступной» оперативной памяти не имеет значения. То, что выделенное виртуальное пространство фактически не использует все это дисковое пространство, не имеет значения. Windows не может «зафиксировать» виртуальное распределение, если только оно не «может» быть полностью сброшено в будущем.
Обратите внимание, что есть еще один тип vas, называемый "mapped", который в основном используется для кода и для доступа к большим файлам данных, но он не тарифицируется "commit charge" и не ограничен "commit limit". Это потому, что он поставляется со своей собственной областью хранения, файлами, которые "отображены" на него. Единственное ограничение на "mapped" vas - это объем дискового пространства, который у вас есть для отображенных файлов, и объем свободного vas в вашем процессе, в который их нужно отобразить.
Но когда я смотрю на систему, я еще не достиг предела по объему вложений?
Это в основном проблема измерения и ведения учета. Вы смотрите на систему после того, как вызов VirtualAlloc уже был опробован и потерпел неудачу.
Предположим, у вас осталось всего 500 МБ лимита фиксации, и какая-то программа попыталась VirtualAlloc 600 МБ. Попытка не удалась. Затем вы смотрите на систему и говорите: «Что? Осталось еще 500 МБ!» На самом деле, к тому времени может остаться гораздо больше, потому что рассматриваемый процесс, скорее всего, к этому моменту полностью исчезнет, так что ВСЯ ранее выделенная им фиксированная память будет освобождена.
Проблема в том, что вы не можете оглянуться назад во времени и увидеть, каков был размер комиссий.былв момент, когда была сделана попытка выделения. И вы также не знаете, сколько места было для этой попытки. Поэтому вы не можете определенно понять, почему попытка не удалась, или насколько больше "предела выделения" потребовалось бы, чтобы она сработала.
Я видел, что «системана исходена память". Что это?
Если в приведенном выше случае ОС МОЖЕТ расширить файл подкачки (т. е. вы оставляете его с настройкой по умолчанию «управляется системой» или управляете им, но устанавливаете максимум больше начального, И на диске достаточно свободного места), и такое расширение увеличивает предел фиксации в достаточной степени, чтобы позволить вызову VirtualAlloc успешно выполниться, то... Mm расширяет файл подкачки, и вызов VirtualAlloc успешно выполняется.
И вот тогда вы видите "system is running LOW on memory". Это раннее предупреждение о том, что если ситуация будет продолжаться без смягчения, вы, скорее всего, скоро увидите предупреждение "out of memory". Пора закрыть некоторые приложения. Я бы начал с окон браузера.
И вы думаете, что это хорошо? Расширение файла подкачки - это зло!!!
Нет, это не так. Видите ли, ОС на самом деле не «расширяет» существующий файл. Она просто выделяет новый экстент. Эффект очень похож на любой другой несмежной файл. Старое содержимое файла подкачки остается там, где оно есть; его не нужно копировать в новое место или что-то в этом роде. Поскольку большинство операций ввода-вывода файла подкачки происходит относительно небольшими порциями по сравнению с размером файла подкачки, вероятность того, что какая-либо данная передача пересечет границу экстента, на самом деле довольно мала, поэтому фрагментация не сильно повредит, если только она не будет действительно чрезмерной.
Наконец, как только все процессы, «занявшие» пространство в расширении, завершатся (при завершении работы ОС, если не раньше), экстенты будут автоматически освобождены, а файл подкачки вернется к своему прежнему размеру и распределению — если до этого он был непрерывным, то станет таковым снова.
Разрешение на расширение файла подкачки, таким образом, действует как совершенно бесплатная страховочная сетка: если вы разрешаете это, но система никогда не нуждается в этом, система не будет «постоянно расширять и сжимать файл подкачки», как часто утверждается, поэтому это будет стоитьничего. А если вам это когда-нибудь понадобится, это убережет вас от сбоев приложений с ошибками «недостаточно виртуальной памяти».
Но но НО...
Я читал на десятках веб-сайтов, что если разрешить расширение файла подкачки, Windows будет постоянно расширять и сжимать файл подкачки, и что это приведет к фрагментации файла подкачки, пока вы не выполните его дефрагментацию.
Они просто ошибаются.
Если вы никогда не видели всплывающего окна «недостаточно памяти» (или, в старых версиях, «недостаточно виртуальной памяти»), значит, ОС никогда не расширяла ваш файл подкачки.
Если вы видите это всплывающее окно, это значит, что ваш начальный размер файла подкачки слишком мал. (Я предпочитаю устанавливать его примерно в 4 раза больше максимального наблюдаемого использования; т. е. счетчик perfmon "%pagefile usage peak" должен быть ниже 25%. Причина: пространство файла подкачки управляется так же, как и любая другая куча, и лучше всего работает с большим количеством свободного места для игры.)
Но почему бы им просто не...
Можно утверждать, что ОС должна просто позволить произойти распределению, а затем позволитьРекомендациисбой, если нет доступной оперативной памяти для устранения ошибок страниц. Другими словами, выше, где мы описали, как работает начальная ошибка страницы, что, если «выделение доступной физической страницы оперативной памяти» (шаг 1) не может быть выполнено, поскольку не было доступной,ине осталось места, чтобы что-то распечатать и сделать доступным?
Тогда пейджер не сможет разрешить ошибку страницы. Ему придется разрешить исключение (ошибку страницы) сообщать обратно в поток, вызвавший ошибку, возможно, измененный на какой-то другой код исключения.
Философия дизайна заключается в том, что VirtualAlloc вернет ноль (технически указатель NULL) вместо адреса, если вы исчерпаете лимит коммита, и вполне разумно ожидать, что программист будет знать, что вызов VirtualAlloc может завершиться неудачей. Поэтому от программистов ожидается проверка этого случая и выполнение разумных действий в ответ (например, предоставление вам возможности сохранить работу до этой точки, а затем «изящное» завершение программы). (Программисты: вы же проверяете возврат указателя NULL из malloc, new и т. д., да? Тогда почему бы вам не сделать этого?)
Но программисты не должны ожидать, что простая ссылка на память, такая как
i = 0; // initialize loop counter
может произойти сбой — не в том случае, если он находится в области успешно выделенного адресного пространства. (Или отображенного адресного пространства, если на то пошло.) Но это то, что может произойти, если следовать философии «разрешить избыточное выделение, позволить ссылке на память дать сбой».
К сожалению, ссылка на память, подобная той, что в строке кода выше, просто не имеет удобного способа вернуть плохой статус! Они просто должныработа, как и сложение и вычитание. Единственный способ сообщить о таких сбоях — это исключения. Поэтому для их обработки программисту пришлось бы обернуть всю программу в обработчик исключений. (попробуйте ... catch и все такое.)
Это можно сделать... Но обработчику будет сложно узнать, как «сделать правильно» в ответ на эти исключения, поскольку в коде будет очень много точек, где они могут возникнуть. (В частности, они могут возникнуть вкаждый(Ссылка на память, выделенную VirtualAlloc, на память, выделенную с помощью malloc или new... а также на все локальные переменные, поскольку стек также выделен VirtualAlloc.)
Короче говоря, в таких случаях заставить программу благополучно завершиться неудачей будет очень сложно.
С другой стороны, довольно легко проверить возврат указателя NULL из VirtualAlloc (или malloc, или new, если на то пошло, хотя это не совсем одно и то же), а затем сделать что-то разумное... например, не пытаться продолжать и делать то, для чего программе было нужно это виртуальное пространство. И, возможно, спросить пользователя, хочет ли он сохранить свою работу на данный момент, если вообще хочет. (Конечно, слишком много приложений не утруждают себя даже этим.)
Другие пользователи commit
Кстати, "лимит фиксации" не уменьшается различными выделениями ОС, такими как выгружаемый и невыгружаемый пул, список PFN и т. д.; они просто взимаются для фиксации платы по мере их возникновения. Также на плату фиксации или лимит фиксации не влияет видеопамять или даже размер "окна" видеопамяти.
Проверьте сами
Вы можете продемонстрировать все это с помощью инструмента testlimit с сайта SysInternals. Опция -m выделит выделенное адресное пространство, но не «тронет» его, поэтому не вызовет выделения ОЗУ. В то время как опция -d выделит и также будет ссылаться на страницы, что приведет как к увеличению платы за выделение, так и к уменьшению доступной ОЗУ.
Рекомендации
Внутреннее устройство WindowsРуссинович, Соломон и Ионеску. Есть даже демонстрации, позволяющие вам доказать все эти пункты с помощью инструмента testlimit. Однако я должен предупредить вас, что если вы думаете, что это длинно, будьте осторожны: глава Mm одна занимает 200 страниц; вышеизложенное — это КРАЙНЕ упрощенная версия. (Пожалуйста, также взгляните на раздел «Благодарности» во Введении.)
Смотрите такжеДокументация MSDN VirtualAlloc
решение2
Может быть, чтобы добавить кблестящий принятый ответ:
Windows и большинство программ предполагают, что они могут выделить столько (виртуальной) памяти, сколько необходимо. Это одна из главных причин, почему не следует отключать файл подкачки, см. предложенныйфакт 2.2вмой вопрос суперпользователя.
Я также ссылаюсь наэтот блестящий ответ на serverfaultвот, что проясняет, как работает файл подкачки:
Многие, похоже, полагают, что Windows помещает данные в файл подкачки по требованию. НАПРИМЕР: что-то требует много памяти, а оперативной памяти недостаточно для удовлетворения этой потребности, поэтому Windows начинает лихорадочно записывать данные из оперативной памяти на диск в эту последнюю минуту, чтобы освободить оперативную память для новых потребностей.
Это неверно. Под капотом происходит больше. В общем, Windows поддерживаетрезервный магазин, что означает, что он хочет видеть все, что находится в памяти, также и на диске где-то. Теперь, когда что-то появляется и требует много памяти, Windows может очистить RAM очень быстро, потому что эти данныеужена диске, готовый к пересылке обратно в ОЗУ, если это потребуется. Так что можно сказать, что многое из того, что находится в файле подкачки, также находится в ОЗУ; данные былипревентивнопомещается в файл подкачки для ускорения новых требований по выделению памяти.
дальнейшее чтениепредоставленздесь