Экономисты знают старую притчу про общий луг, на который каждый пастух выгоняет лишнюю корову, потому что корова его, а трава общая: луг вскоре оказывается вытоптан, и страдают все. Современный компьютер переживает эту драму каждый час своей работы. Браузер отъедает память, как пастух с табуном, мессенджер в трее оставляет себе пару сотен мегабайт про запас, служба подготовки обновлений прячет своё стадо, а пользователь в это время удивляется: откуда при шестнадцати гигабайтах вдруг нет свободной памяти. Внутри микросхем ОЗУ ежесекундно разыгрывается тихая борьба за ресурс, и разобраться в её законах полезно всякому, кто когда-нибудь ворчал на медленный ноутбук.
Виртуальная память как великий миротворец
До зрелых механизмов управления памятью каждая программа сама держала в уме, сколько ей позволено занять, и договаривалась с соседями вручную. Времена были честные и неудобные: оверлеи, ручная подгрузка кусков программы с диска, жёсткие границы. Всё переменила идея виртуальной памяти, у которой простая гениальная суть: каждой программе рисуют её собственное сплошное адресное пространство, словно она в машине одна-одинешенька, а операционная система за кулисами раскладывает виртуальные страницы по реальным чипам и диску как умеет.
Механизм требует поддержки с двух сторон: процессор несёт в себе блок управления памятью, транслирующий виртуальные адреса в физические, а операционная система руководит раздачей: решает, какая страница живёт в ОЗУ, какая отправляется покемарить в файл подкачки, какая может быть прочитана из файла по требованию. Для программы всё происходит совершенно прозрачно, и программист избавлен от ручной возни, а соседские программы избавлены друг от друга: адресные пространства не пересекаются, и ваша соседка по подкачке не может залезть вам в карман.
Родство виртуальной памяти и трагедии общин в том, что самое блестящее её свойство есть и главное её искушение. Каждой программе обещан свой мир, и этот мир стоит столько, сколько программа осмелится запросить. Когда запросы полсотни процессов суммарно превышают физическую память, наступает время решать, кто в машине важнее.
Почему программам нравится притворяться первыми леди
Производители софта не злы и не забывчивы, они просто думают о собственном зрителе. Программа, которая запускается шустро и отвечает мгновенно, обычно подминает под себя память: кэширует картинки, держит заранее готовые структуры данных, грузит в оперативку весь словарь мира. Для неё это означает медали за отзывчивость, а для соседей медленный душ. Каждый разработчик решает задачу локально, а локальная логика сходится в классическую трагедию общего пастбища.
Самые громкие протагонисты этой драмы известны любому пользователю. Современный браузер с отдельным процессом на вкладку способен лакомиться памятью гигабайтами, мессенджеры хранят в памяти всю живую анимацию стикеров, видеоредакторы не извиняются вовсе, а редкая игра при старте не потребует заливать оперативку текстурами вперёд тормозов. Каждая строка в этом списке аморальна только наполовину: никто не нарушает закон, все просто пользуются тем, что пастбище выглядит необъятным.
Особый клан составляют программы с самомнением системной важности: фоновые помощники, обновляторы, сборщики телеметрии, сервисы подготовки полупрозрачной красоты. Количеству их нет числа, повод присутствия у каждого уважительный, а итог в совокупности один и тот же: свободных гигабайтов меньше, чем куплено.
Как операционная система судит спорящих соседей
У системы есть инструменты для урегулирования конфликтов, и они образуют настоящую нравственную иерархию. Тонкий инструмент это подкачка: редко используемые страницы памяти у складных процессов отправляются в файл подкачки на диск, освобождая место для того, кто работает сейчас. Когда программа вдруг вспоминает про выгнанные страницы, случается ошибка страницы, система гневно влетает на диск и возвращает кусок назад. Пользователь в этот момент слышит шуршание накопителя и видит малюсенькую паузу в отклике.
Грубый инструмент состоит в изгнании. Когда память по-настоящему кончается, операционная система выбирает лишний процесс. В Linux для этого существует прямолинейный механизм, известный как OOM killer, убийца при нехватке памяти: он оценивает процессы по системе баллов и завершает того, кто жирнее и менее ценен. В мобильных системах лавина происходит иначе: фоновые приложения благородно замораживаются или выгружаются, и пользователь замечает это по холодному перезапуску программы при возвращении в неё.
Windows идёт средним путём семейства компромиссов: агрессивное использование кэша, служба SysMain, предугадывающая нужные страницы заранее, сжатие маловостребованных областей памяти, аккуратная работа с файлом подкачки. Отсюда банальный совет знающего пользователя: столбец "свободная память" в диспетчере задач давно ничего не означает, современные системы сознательно наполняют ОЗУ кэшем, потому что простаивающая память есть память бесполезная.
Уроки трагедии для владельца машины
Из клубка взаимных хищений памятью можно вытащить несколько здравых привычек:
- Следите не за заполненностью памяти, а за наличием свободного отклика: паузы и шуршание вместо цифр;
- Закрывайте тяжёлые вкладки браузера - они первые кандидаты на корону эгоиста;
- Почистите список автозагрузки: каждый фоновый помощник платит вам заниженным откликом;
- Если приходится выбирать между обновлением ОЗУ и обновлением накопителя, часто дельнее память, но твердотельный накопитель сглаживает саму боль подкачки;
- Примиритесь с кэшем: система, заполнившая память полезными под запас структурами, работает отзывчивее, а не медленнее.
Отдельным абзацем стоят игры и тяжёлые редакторы: им хорошо там, где ОЗУ просторно, и обновление памяти для таких сценариев нередко заметнее смены процессора. Правда, честная гигабайтовая расчёска всегда касается и программ: в современном мире софта редко встречается мотивация экономить, потому что экономию всё равно съест сосед. По этой причине оперативная память остаётся классическим узким горлышком массового компьютера.
История вопроса от оверлеев до страничной подкачки
Полезно взглянуть, как выглядела эта проблема на заре вычислительной техники. В сороковые и пятидесятые годы программы, превышавшие скромный запас оперативной памяти, обязаны были сами тащить на себе логику перемещения частей туда-сюда между памятью и накопителем, то есть накладывать на себя так называемые оверлеи. Программист писал не только алгоритм, но и логистику его загрузки, и любая перекладка требовала заново решать, какие куски кода сейчас должны быть рядом.
С изобретением виртуальной памяти вся эта возня переехала на плечи операционной системы и специального блока процессора. Западная литература подчёркивает, что новшество было введено не столько ради объёма, сколько ради удобства программистов: простота оказалась настолько соблазнительной, что сегодня виртуальная память аппаратно поддерживается в подавляющем большинстве современных процессоров. Лишь в микроконтроллерах и системах реального времени, где важен мгновенный отклик и запрет на паузы, от этой роскоши отказываются.
Житейское следствие этой победы видно невооружённым глазом: современный пользователь не задумывается о том, как двести процессов делят шестнадцать гигабайт, потому что вся адресация и вся вытесняющая логистика делаются без его участия. Одна строчка ядра сказала программам "ты живёшь одна", и каждая потом вежливо притворяется именно такой - вплоть до того момента, когда подкачка начинает стучать в пол.
Тонкая политика кэша и почему пустая память не добродетель
Особого рассказа заслуживает непривычное новичку явление: полная память как знак здоровья. Старые утилиты пугают пользователя строкой "свободно двести мегабайт", и испуганный хозяин начинает вычищать всё подряд. В современных системах эта цифра на самом деле сообщает не бедность, а нерасторопность: зачем держать память пустой, если в неё можно заранее замести файлы, которые понадобятся в ближайшие минуты. Кэш не занимает память у программ, он лишь пользуется свободным местом, и тут же освобождает его, когда появляется настоящий жилец.
Разумное отношение к этому механизму состоит в том, чтобы смотреть на отзывчивость системы, а не на приборную стрелку заполненности. Если компьютер шустро открывает окна и не пыхтит за дисковой подкачкой, память в порядке, чего бы ни показывала диаграмма. Именно поэтому технические службы тихо не любят инструменты, обещающие "освободить оперативную память одним щелчком": такие программы чаще всего выгоняют кэш вон, диску становится больше работы, а пользователю светит только микросекундный кайф созерцания красивой цифры.
Когда кончается память, замечают все
Краевая ситуация при полном исчерпании ресурса описывается житейски просто: всё тормозит, и в вазе с паузами видны глубокие царапины. Система лихорадочно двигает страницы между памятью и диском, диспетчер задач показывает стопроцентную оккупацию, и даже проводник словно бы спотыкается о собственные ресницы. Эта картина встречается реже, чем кажется, но запоминается надолго, и именно в такие минуты пользователь обретает настоящее понимание главного закона цифровой коллективности: общее благо редко кто-то охраняет осознанно, его охраняет лишь дисциплина участников.
Инженерная культура отвечает на этот вызов развитием давления изнутри: современные версии Windows и macOS умеют сжимать холодные страницы, устроены умнее при изгнании фоновых программ и лучше предугадывают стартап-операции. Однако фундаментальную горизонталь никто не переписывал: пастбище конечно даже тогда, когда процветает эффект сжатия, и мудрость пользователя по-прежнему замешана на достатке.
Маленький манифест экономного софта и уважительного пользователя.
В конце концов трагедия общего пастбища в оперативной памяти это вовсе не повод ругать программы: у каждой из них найдутся свои резоны, и многие крупные расходы объясняются искренней заботой о скорости для пользователя. Повод рождается, как водится, не в отдельной программе, а в сумме: сорок милых служб потребляют как один большой зверь, а предъявить претензию не получается никому, потому что каждый в отдельности выглядит прилично. Из этой конфигурации вырастает урок о ценности мерочек: уборка автозапуска, сдержанное количество вкладок, снос забытых программ будто поит пастбище и возвращает жирок траве. Память любит порядок едва ли не сильнее, чем объём, и та же аппаратная машина после недели вежливого минимализма нередко кажется другим компьютером.
Занавес над пастбищем.
Общая оперативная память была и остаётся самой элегантной иллюстрацией того, как маленькие локальные оптимизации накапливаются в большую общую беду. Исправить ситуацию в корне нельзя, потому что стимулы её создают. Сгладить её можно привычкой, немного дисциплины в выборе программ, немного щедрости при покупке железа и щепоть доверия к операционной системе, которая старательно раздаёт страницы и в целом переживает за ваш комфорт больше, чем кажется. Тогда коровы остаются довольны, пастухи не ссорятся, а на лугу долго ещё остаётся живая зелень.
Зачем вообще стоит понимать эту механику.
Знающий пользователь отличается от раздражённого пользователя одной способностью: он понимает, почему его ноутбук медлит после запуска вороха программ, и может изменить картину одним движением вместо стона. Трагедия общего пастбища в ОЗУ неизлечима в принципе, потому что каждая программа оптимизирует свой собственный успех, а успеха общего опыта гарантирует только совесть разработчиков и распорядительность операционной системы. Однако смягчается она дорогостояще просто: чуть более разумным выбором программ, чуть более спокойным отношением к цифрам и чуть более щедрым запасом гигабайтов при покупке. И пастух, и луг при этом остаются на своих местах, только лужайка перестаёт выглядеть вытоптанной.