Программа в оперативной памяти это
Привет, Хабр! Представляю вашему вниманию перевод статьи «Demystifying memory management in modern programming languages» за авторством Deepu K Sasidharan.
В данной серии статей мне бы хотелось развеять завесу мистики над управлением памятью в программном обеспечении (далее по тексту — ПО) и подробно рассмотреть возможности, предоставляемые современными языками программирования. Надеюсь, что мои статьи помогут читателю заглянуть под капот этих языков и узнать для себя нечто новое.
Углублённое изучение концептов управления памятью позволяет писать более эффективное ПО, потому как стиль и практики кодирования оказывают большое влияние на принципы выделения памяти для нужд программы.
Часть 1: Введение в управление памятью
Управление памятью — это целый набор механизмов, которые позволяют контролировать доступ программы к оперативной памяти компьютера. Данная тема является очень важной при разработке ПО и, при этом, вызывает затруднения или же вовсе остаётся черным ящиком для многих программистов.
Для чего используется оперативная память?
Когда программа выполняется в операционный системе компьютера, она нуждается в доступе к оперативной памяти (RAM) для того, чтобы:
- загружать свой собственный байт-код для выполнения;
- хранить значения переменных и структуры данных, которые используются в процессе работы;
- загружать внешние модули, которые необходимы программе для выполнения задач.
Стек используется для статичного выделения памяти. Он организован по принципу «последним пришёл — первым вышел» (LIFO). Можно представить стек как стопку книг — разрешено взаимодействовать только с самой верхней книгой: прочитать её или положить на неё новую.
- благодаря упомянутому принципу, стек позволяет очень быстро выполнять операции с данными — все манипуляции производятся с «верхней книгой в стопке». Книга добавляется в самый верх, если нужно сохранить данные, либо берётся сверху, если данные требуется прочитать;
- существует ограничение в том, что данные, которые предполагается хранить в стеке, обязаны быть конечными и статичными — их размер должен быть известен ещё на этапе компиляции;
- в стековой памяти хранится стек вызовов — информация о ходе выполнения цепочек вызовов функций в виде стековых кадров. Каждый стековый кадр это набор блоков данных, в которых хранится информация, необходимая для работы функции на определённом шаге — её локальные переменные и аргументы, с которыми её вызывали. Например, каждый раз, когда функция объявляет новую переменную, она добавляет её в верхний блок стека. Затем, когда функция завершает свою работу, очищаются все блоки памяти в стеке, которые функция использовала — иными словами, очищаются все блоки ее стекового кадра;
- каждый поток многопоточного приложения имеет доступ к своему собственному стеку;
- управление стековой памятью простое и прямолинейное; оно выполняется операционной системой;
- в стеке обычно хранятся данные вроде локальных переменных и указателей;
- при работе со стеком есть вероятность получать ошибки переполнения стека (stack overflow), так как максимальный его размер строго ограничен. Например, ошибка при составлении граничного условия в рекурсивной функции совершенно точно приведёт к переполнению стека;
- в большинстве языков существует ограничение на размер значений, которые можно сохранить в стек;
Использование стека в JavaScript. Объекты хранятся в куче и доступны по ссылкам, которые хранятся в стеке. Тут можно посмотреть в видеоформате
Куча используется для динамического выделения памяти, однако, в отличие от стека, данные в куче первым делом требуется найти с помощью «оглавления». Можно представить, что куча это такая большая многоуровневая библиотека, в которой, следуя определённым инструкциям, можно найти необходимую книгу.
- операции на куче производятся несколько медленнее, чем на стеке, так как требуют дополнительного этапа для поиска данных;
- в куче хранятся данные динамических размеров, например, список, в который можно добавлять произвольное количество элементов;
- куча общая для всех потоков приложения;
- вследствие динамической природы, куча нетривиальна в управлении и с ней возникает большинство всех проблем и ошибок, связанных с памятью. Способы решения этих проблем предоставляются языками программирования;
- типичные структуры данных, которые хранятся в куче — это глобальные переменные (они должны быть доступны для разных потоков приложения, а куча как раз общая для всех потоков), ссылочные типы, такие как строки или ассоциативные массивы, а так же другие сложные структуры данных;
- при работе с кучей можно получить ошибки выхода за пределы памяти (out of memory), если приложение пытается использовать больше памяти, чем ему доступно;
- размер значений, которые могут храниться в куче, ограничен лишь общим объёмом памяти, который был выделен операционной системой для программы.
Почему эффективное управление памятью важно?
В отличие от жёстких дисков, оперативная память весьма ограниченна (хотя и жёсткие диски, безусловно, тоже не безграничны). Если программа потребляет память не высвобождая её, то, в конечном итоге, она поглотит все доступные резервы и попытается выйти за пределы памяти. Тогда она просто упадет сама, или, что ещё драматичнее, обрушит операционную систему. Следовательно, весьма нежелательно относиться легкомысленно к манипуляциям с памятью при разработке ПО.
Различные подходы
Современные языки программирования стараются максимально упростить работу с памятью и снять с разработчиков часть головной боли. И хотя некоторые почтенные языки всё ещё требуют ручного управления, большинство всё же предоставляет более изящные автоматические подходы. Порой в языке используется сразу несколько подходов к управлению памятью, а иногда разработчику даже доступен выбор какой из вариантов будет эффективнее конкретно для его задач (хороший пример — C++). Перейдём к краткому обзору различных подходов.
Ручное управление памятью
Язык не предоставляет механизмов для автоматического управления памятью. Выделение и освобождение памяти для создаваемых объектов остаётся полностью на совести разработчика. Пример такого языка — C. Он предоставляет ряд методов (malloc, realloc, calloc и free) для управления памятью — разработчик должен использовать их для выделения и освобождения памяти в своей программе. Этот подход требует большой аккуратности и внимательности. Так же он является в особенности сложным для новичков.
Сборщик мусора
Получение ресурса есть инициализация (RAII)
RAII — это программная идиома в ООП, смысл которой заключается в том, что выделяемая для объекта область памяти строго привязывается к его времени существования. Память выделяется в конструкторе и освобождается в деструкторе. Данный подход был впервые реализован в C++, а так же используется в Ada и Rust.
Автоматический подсчёт ссылок (ARC)
Данный подход весьма похож на сборку мусора с подсчётом ссылок, однако, вместо запуска процесса подсчёта в определённые интервалы времени, инструкции выделения и освобождения памяти вставляются на этапе компиляции прямо в байт-код. Когда же счётчик ссылок достигает нуля, память освобождается как часть нормального потока выполнения программы.
Автоматический подсчёт ссылок всё так же не позволяет обрабатывать циклические ссылки и требует от разработчика использования специальных ключевых слов для дополнительной обработки таких ситуаций. ARC является одной из особенностей транслятора Clang, поэтому присутствует в языках Objective-C и Swift. Так же автоматический подсчет ссылок доступен для использования в Rust и новых стандартах C++ при помощи умных указателей.
Владение
Это сочетание RAII с концепцией владения, когда каждое значение в памяти должно иметь только одну переменную-владельца. Когда владелец уходит из области выполнения, память сразу же освобождается. Можно сказать, что это примерно как подсчёт ссылок на этапе компиляции. Данный подход используется в Rust и при этом я не смог найти ни одного другого языка, который бы использовал подобный механизм.
В данной статье были рассмотрены основные концепции в сфере управления памятью. Каждый язык программирования использует собственные реализации этих подходов и оптимизированные для различных задач алгоритмы. В следующих частях, мы подробнее рассмотрим решения для управления памятью в популярных языках.
Читайте так же другие части серии:
Ссылки
Вы можете подписаться на автора статьи в Twitter и на LinkedIn.
За вычитку перевода отдельное спасибо Александру Максимовскому и Катерине Шибаковой
Управление памятью – одна из главных задач ОС. Она критична как для программирования, так и для системного администрирования. Я постараюсь объяснить, как ОС работает с памятью. Концепции будут общего характера, а примеры я возьму из Linux и Windows на 32-bit x86. Сначала я опишу, как программы располагаются в памяти.
Каждый процесс в многозадачной ОС работает в своей «песочнице» в памяти. Это виртуальное адресное пространство, которое в 32-битном режиме представляет собою 4Гб блок адресов. Эти виртуальные адреса ставятся в соответствие (mapping) физической памяти таблицами страниц, которые поддерживает ядро ОС. У каждого процесса есть свой набор таблиц. Но если мы начинаем использовать виртуальную адресацию, приходится использовать её для всех программ, работающих на компьютере – включая и само ядро. Поэтому часть пространства виртуальных адресов необходимо резервировать под ядро.
Это не значит, что ядро использует так много физической памяти – просто у него в распоряжении находится часть адресного пространства, которое можно поставить в соответствие необходимому количеству физической памяти. Пространство памяти для ядра отмечено в таблицах страниц как эксклюзивно используемое привилегированным кодом, поэтому если какая-то программа пытается получить в него доступ, случается page fault. В Linux пространство памяти для ядра присутствует постоянно, и ставит в соответствие одну и ту же часть физической памяти у всех процессов. Код ядра и данные всегда имеют адреса, и готовы обрабатывать прерывания и системные вызовы в любой момент. Для пользовательских программ, напротив, соответствие виртуальных адресов реальной памяти меняется, когда происходит переключение процессов:
Голубым отмечены виртуальные адреса, соответствующие физической памяти. Белым – пространство, которому не назначены адреса. В нашем примере Firefox использует гораздо больше места в виртуальной памяти из-за своей легендарной прожорливости. Полоски в адресном пространстве соответствуют сегментам памяти таким, как куча, стек и проч. Эти сегменты – всего лишь интервалы адресов памяти, и не имеют ничего общего с сегментами от Intel. Вот стандартная схема сегментов у процесса под Linux:
Когда программирование было белым и пушистым, начальные виртуальные адреса сегментов были одинаковыми для всех процессов. Это позволяло легко удалённо эксплуатировать уязвимости в безопасности. Зловредной программе часто необходимо обращаться к памяти по абсолютным адресам – адресу стека, адресу библиотечной функции, и т.п. Удаленные атаки приходилось делать вслепую, рассчитывая на то, что все адресные пространства остаются на постоянных адресах. В связи с этим получила популярность система выбора случайных адресов. Linux делает случайными стек, сегмент отображения в память и кучу, добавляя смещения к их начальным адресам. К сожалению, в 32-битном адресном пространстве особо не развернёшься, и для назначения случайных адресов остаётся мало места, что делает эту систему не слишком эффективной.
Самый верхний сегмент в адресном пространстве процесса – это стек, в большинстве языков хранящий локальные переменные и аргументы функций. Вызов метода или функции добавляет новый кадр стека (stack frame) к существующему стеку. После возврата из функции кадр уничтожается. Эта простая схема приводит к тому, что для отслеживания содержимого стека не требуется никакой сложной структуры – достаточно всего лишь указателя на начало стека. Добавление и удаление данных становится простым и однозначным процессом. Постоянное повторное использование районов памяти для стека приводит к кэшированию этих частей в CPU, что добавляет скорости. Каждый поток выполнения (thread) в процессе получает свой собственный стек.
Можно прийти к такой ситуации, в которой память, отведённая под стек, заканчивается. Это приводит к ошибке page fault, которая в Linux обрабатывается функцией expand_stack(), которая, в свою очередь, вызывает acct_stack_growth(), чтобы проверить, можно ли ещё нарастить стек. Если его размер не превышает RLIMIT_STACK (обычно это 8 Мб), то стек увеличивается и программа продолжает исполнение, как ни в чём не бывало. Но если максимальный размер стека достигнут, мы получаем переполнение стека (stack overflow) и программе приходит ошибка Segmentation Fault (ошибка сегментации). При этом стек умеет только увеличиваться – подобно государственному бюджету, он не уменьшается обратно.
Динамический рост стека – единственная ситуация, в которой может осуществляться доступ к свободной памяти, которая показана белым на схеме. Все другие попытки доступа к этой памяти вызывают ошибку page fault, приводящую к Segmentation Fault. А некоторые занятые области памяти служат только для чтения, поэтому попытки записи в эти области также приводят к Segmentation Fault.
После стека идёт сегмент отображения в память. Тут ядро размещает содержимое файлов напрямую в памяти. Любое приложение может запросить сделать это через системный вызов mmap() в Linux или CreateFileMapping() / MapViewOfFile() в Windows. Это удобный и быстрый способ организации операций ввода и вывода в файлы, поэтому он используется для подгрузки динамических библиотек. Также возможно создать анонимное место в памяти, не связанное с файлами, которое будет использоваться для данных программы. Если вы сделаете в Linux запрос на большой объём памяти через malloc(), библиотека C создаст такую анонимное отображение вместо использования памяти из кучи. Под «большим» подразумевается объём больший, чем MMAP_THRESHOLD (128 kB по умолчанию, он настраивается через mallopt().)
Если в куче оказывается недостаточно места для выполнения запроса, эту проблему может обработать сама программа без вмешательства ядра. В ином случае куча увеличивается системным вызовом brk(). Управление кучей – дело сложное, оно требует хитроумных алгоритмов, которые стремятся работать быстро и эффективно, чтобы угодить хаотичному методу размещению данных, которым пользуется программа. Время на обработку запроса к куче может варьироваться в широких пределах. В системах реального времени есть специальные инструменты для работы с ней. Кучи тоже бывают фрагментированными:
И вот мы добрались до самой нижней части схемы – BSS, данные и текст программы. BSS и данные хранят статичные (глобальные) переменные в С. Разница в том, что BSS хранит содержимое непроинициализированных статичных переменных, чьи значения не были заданы программистом. Кроме этого, область BSS анонимна, она не соответствует никакому файлу. Если вы пишете static int cntActiveUsers , то содержимое cntActiveUsers живёт в BSS.
Сегмент данных, наоборот, содержит те переменные, которые были проинициализированы в коде. Эта часть памяти соответствует бинарному образу программы, содержащему начальные статические значения, заданные в коде. Если вы пишете static int cntWorkerBees = 10 , то содержимое cntWorkerBees живёт в сегменте данных, и начинает свою жизнь как 10. Но, хотя сегмент данных соответствует файлу программы, это приватное отображение в память (private memory mapping) – а это значит, что обновления памяти не отражаются в соответствующем файле. Иначе изменения значения переменных отражались бы в файле, хранящемся на диске.
Пример данных на диаграмме будет немного сложнее, поскольку он использует указатель. В этом случае содержимое указателя, 4-байтный адрес памяти, живёт в сегменте данных. А строка, на которую он показывает, живёт в сегменте текста, который предназначен только для чтения. Там хранится весь код и разные другие детали, включая строковые литералы. Также он хранит ваш бинарник в памяти. Попытки записи в этот сегмент оканчиваются ошибкой Segmentation Fault. Это предотвращает ошибки, связанные с указателями (хотя не так эффективно, как если бы вы вообще не использовали язык С). На диаграмме показаны эти сегменты и примеры переменных:
Изучить области памяти Linux-процесса можно, прочитав файл /proc/pid_of_process/maps. Учтите, что один сегмент может содержать много областей. К примеру, у каждого файла, сдублированного в память, есть своя область в сегменте mmap, а у динамических библиотек – дополнительные области, напоминающие BSS и данные. Кстати, иногда, когда люди говорят «сегмент данных», они имеют в виду данные + bss + кучу.
Бинарные образы можно изучать при помощи команд nm и objdump – вы увидите символы, их адреса, сегменты, и т.п. Схема виртуальных адресов, описанная в этой статье – это т.н. «гибкая» схема, которая по умолчанию используется уже несколько лет. Она подразумевает, что переменной RLIMIT_STACK присвоено какое-то значение. В противном случае Linux использует «классическую» схему:
Управление памятью – центральный аспект в работе операционных систем. Он оказывает основополагающее влияние на сферу программирования и системного администрирования. В нескольких последующих постах я коснусь вопросов, связанных с работой памяти. Упор будет сделан на практические аспекты, однако и детали внутреннего устройства игнорировать не будем. Рассматриваемые концепции являются достаточно общими, но проиллюстрированы в основном на примере Linux и Windows, выполняющихся на x86-32 компьютере. Первый пост описывает организацию памяти пользовательских процессов.
Каждый процесс в многозадачной ОС выполняется в собственной “песочнице”. Эта песочница представляет собой виртуальное адресное пространство, которое в 32-битном защищенном режиме всегда имеет размер равный 4 гигабайтам. Соответствие между виртуальным пространством и физической памятью описывается с помощью таблицы страниц (page table). Ядро создает и заполняет таблицы, а процессор обращается к ним при необходимости осуществить трансляцию адреса. Каждый процесс работает со своим набором таблиц. Есть один важный момент — концепция виртуальной адресации распространяется на все выполняемое ПО, включая и само ядро. По этой причине для него резервируется часть виртуального адресного пространства (т.н. kernel space).
Синим цветом на рисунке отмечены области виртуального адресного пространства, которым в соответствие поставлены участки физической памяти; белым цветом — еще не использованные области. Как видно, Firefox использовал большую часть своего виртуального адресного пространства. Все мы знаем о легендарной прожорливости этой программы в отношении оперативной памяти. Синие полосы на рисунке — это сегменты памяти программы, такие как куча (heap), стек и так далее. Обратите внимание, что в данном случае под сегментами мы подразумеваем просто непрерывные адресные диапазоны. Это не те сегменты, о которых мы говорим при описании сегментации в Intel процессорах. Так или иначе, вот стандартная схема организации памяти процесса в Linux:
Давным давно, когда компьютерная техника находилась в совсем еще младенческом возрасте, начальные виртуальные адреса сегментов были совершенно одинаковыми почти для всех процессов, выполняемых машиной. Из-за этого значительно упрощалось удаленное эксплуатирование уязвимостей. Эксплойту часто необходимо обращаться к памяти по абсолютным адресам, например по некоторому адресу в стеке, по адресу библиотечной функции, и тому подобное. Хакер, рассчитывающий осуществить удаленную атаку, должен выбирать адреса для обращения в слепую в расчете на то, что размещение сегментов программы в памяти на разных машинах будет идентичным. И когда оно действительно идентичное, случается, что людей хакают. По этой причине, приобрел популярность механизм рандомизации расположения сегментов в адресном пространстве процесса. Linux рандомизирует расположение стека, сегмента для memory mapping, и кучи – их стартовый адрес вычисляется путем добавления смещения. К сожалению, 32-битное пространство не очень-то большое, и эффективность рандомизации в известной степени нивелируется.
В верхней части user mode space расположен стековый сегмент. Большинство языков программирования используют его для хранения локальных переменных и аргументов, переданных в функцию. Вызов функции или метода приводит к помещению в стек т.н. стекового фрейма. Когда функция возвращает управление, стековый фрейм уничтожается. Стек устроен достаточно просто — данные обрабатываются в соответствии с принципом «последним пришёл — первым обслужен» (LIFO). По этой причине, для отслеживания содержания стека не нужно сложных управляющих структур – достаточно всего лишь указателя на верхушку стека. Добавление данных в стек и их удаление – быстрая и четко определенная операция. Более того, многократное использование одних и тех же областей стекового сегмента приводит к тому, что они, как правило, находятся в кеше процессора, что еще более ускоряет доступ. Каждый тред в рамках процесса работает с собственным стеком.
Возможна ситуация, когда пространство, отведенное под стековый сегмент, не может вместить в себя добавляемые данные. В результате, будет сгенерирован page fault, который в Linux обрабатывается функцией expand_stack(). Она, в свою очередь, вызовет другую функцию — acct_stack_growth(), которая отвечает за проверку возможности увеличить стековый сегмент. Если размер стекового сегмента меньше значения константы RLIMIT_STACK (обычно 8 МБ), то он наращивается, и программа продолжает выполняться как ни в чем не бывало. Это стандартный механизм, посредством которого размер стекового сегмента увеличивается в соответствии с потребностями. Однако, если достигнут максимально разрещённый размер стекового сегмента, то происходит переполнение стека (stack overflow), и программе посылается сигнал Segmentation Fault. Стековый сегмент может увеличиваться при необходимости, но никогда не уменьшается, даже если сама стековая структура, содержащаяся в нем, становиться меньше. Подобно федеральному бюджету, стековый сегмент может только расти.
Динамическое наращивание стека – единственная ситуация, когда обращение к «немэппированной» области памяти, может быть расценено как валидная операция. Любое другое обращение приводит к генерации page fault, за которым следует Segmentation Fault. Некоторые используемые области помечены как read-only, и обращение к ним также приводит к Segmentation Fault.
Под стеком располагается сегмент для memory mapping. Ядро использует этот сегмент для мэппирования (отображания в память) содержимого файлов. Любое приложение может воспользоваться данным функционалом посредством системного вызовома mmap() (ссылка на описание реализации вызова mmap) или CreateFileMapping() / MapViewOfFile() в Windows. Отображение файлов в память – удобный и высокопроизводительный метод файлового ввода / вывода, и он используется, например, для загрузки динамических библиотек. Существует возможность осуществить анонимное отображение в память (anonymous memory mapping), в результате чего получим область, в которую не отображен никакой файл, и которая вместо этого используется для размещения разного рода данных, с которыми работает программа. Если в Linux запросить выделение большого блока памяти с помощью malloc(), то вместо того, чтобы выделить память в куче, стандартная библиотека C задействует механизм анонимного отображения. Слово «большой», в данном случае, означает величину в байтах большую, чем значение константы MMAP_THRESHOLD. По умолчанию, это величина равна 128 кБ, и может контролироваться через вызов mallopt().
Если текущий размер кучи позволяет выделить запрошенный объем памяти, то выделение может быть осуществлено средствами одной лишь среды выполнения, без привлечения ядра. В противном случае, функция malloc() задействует системный вызов brk() для необходимого увеличения кучи (ссылка на описание реализации вызова brk). Управление памятью в куче – нетривиальная задача, для решения которой используются сложные алгоритмы. Данные алгоритмы стремятся достичь высокой скорости и эффективности в условиях непредсказуемых и хаотичных пэттернов выделения памяти в наших программах. Время, затрачиваемое на каждый запрос по выделению памяти в куче, может разительно отличаться. Для решения данной проблемы, системы реального времени используют специализированные аллокаторы памяти. Куча также подвержена фрагментированию, что, к примеру, изображено на рисунке:
Наконец, мы добрались до сегментов, расположенных в нижней части адресного пространства процесса: BSS, сегмент данных (data segment) и сегмент кода (text segment). BSS и data сегмент хранят данные, соответствующий static переменным в исходном коде на C. Разница в том, что в BSS хранятся данные, соответствующие неинициализированным переменным, чьи значения явно не указаны в исходном коде (в действительности, там хранятся объекты, при создании которых в декларации переменной либо явно указано нулевое значение, либо значение изначально не указано, и в линкуемых файлах нет таких же common символов, с ненулевым значением. – прим. перевод.). Для сегмента BSS используется анонимное отображение в память, т.е. никакой файл в этот сегмент не мэппируется. Если в исходном файле на C использовать int cntActiveUsers, то место под соответствующий объект будет выделено в BSS.
В отличии от BSS, data cегмент хранит объекты, которым в исходном коде соответствуют декларации static переменных, инициализированных ненулевым значением. Этот сегмент памяти не является анонимным — в него мэппируется часть образа программы. Таким образом, если мы используем static int cntWorkerBees = 10, то место под соответствующий объект будет выделено в data сегменте, и оно будет хранить значение 10. Хотя в data сегмент отображается файл, это т.н. «приватный мэппинг» (private memory mapping). Это значит, что изменения данных в этом сегменте не повлияют на содержание соответствующего файла. Так и должно быть, иначе присвоения значений глобальным переменным привели бы к изменению содержания файла, хранящегося на диске. В данном случае это совсем не нужно!
С указателями все немножко посложнее. В примере из наших диаграмм, содержимое объекта, соответствующего переменной gonzo – это 4-байтовый адрес – размещается в data сегменте. А вот строка, на которую ссылается указатель, не попадет в data сегмент. Строка будет находиться в сегменте кода, который доступен только на чтение и хранит весь Ваш код и такие мелочи, как, например, строковые литералы (в действительности, строка хранится в секции .rodata, которая вместе с другими секциями, содержащими исполняемый код, рассматривается как сегмент, который загружается в память с правами на выполнение кода / чтения данных – прим. перевод.). В сегмент кода также мэппируется часть исполняемого файла. Если Ваша программа попытается осуществить запись в text сегмент, то заработает Segmentation Fault. Это позволяет бороться с «бажными» указателями, хотя самый лучший способ борьбы с ними – это вообще не использовать C. Ниже приведена диаграмма, изображающая сегменты и переменные из наших примеров:
Мы можем посмотреть, как используются области памяти процесса, прочитав содержимое файла /proc/pid_of_process/maps. Обратите внимание, что содержимое самого сегмента может состоять из различных областей. Например, каждой мэппируемой в memory mapping сегмент динамической библиотеке отводится своя область, и в ней можно выделить области для BSS и data сегментов библиотеки. В следующем посте поясним, что конкретно подразумевается под словом “область”. Учтите, что иногда люди говорят “data сегмент”, подразумевая под этим data + BSS + heap.
Можно использовать утилиты nm и objdump для просмотра содержимого бинарных исполняемых образов: символов, их адресов, сегментов и т.д. Наконец, то, что описано в этом посте – это так называемая “гибкая” организация памяти процесса (flexible memory layout), которая вот уже несколько лет используется в Linux по умолчанию. Данная схема предполагает, что у нас определено значение константы RLIMIT_STACK. Когда это не так, Linux использует т.н. классическую организации, которая изображена на рисунке:
Ну вот и все. На этом наш разговор об организации памяти процесса завершен. В следующем посте рассмотрим как ядро отслеживает размеры описанных областей памяти. Также коснемся вопроса мэппирования, какое отношение к этому имеет чтение и запись файлов, и что означают цифры, описывающие использование памяти.
Когда вы используете всю доступную оперативную память на вашем компьютере, вы можете заметить, что ваше устройство начинает работать медленнее, а система и установленные приложения начинают «бороться» за доступную оперативную память при выполнении своих задач. Если вы обнаружите, что приложения вашего компьютера часто сбоят и требуется больше времени для выполнения простых задач, то вам может быть интересно, как высвободить оперативную память на вашем компьютере.
Что такое ОЗУ?
Оперативная память (ОЗУ, или по-английски RAM) вашего компьютера хранится на чипе памяти, который обычно находится на материнской плате. Это место, где ваш компьютер хранит краткосрочные данные. Оперативная память – это центр хранения всех активных и запущенных программ и процессов. Ваш компьютер использует информацию, хранящуюся в оперативной памяти, для выполнения задач, одновременно получая и выполняя другие функции.
Когда вы используете всю доступную оперативную память, производительность вашего компьютера может замедлиться, потому что у него уже нет хранилища, необходимого для выполнения своих задач. Когда вы очищаете пространство оперативной памяти, это дает вашему компьютеру возможность быстрее выполнять свои задачи. В зависимости от того, какой у вас компьютер, существует несколько различных способов, как можно высвободить место в оперативной памяти.
Как максимально эффективно использовать вашу оперативную память
Достичь использования всей доступной оперативной памяти достаточно легко, потому что она поддерживает очень много функций. Прежде чем вы начнете удалять программы с компьютера, попробуйте выполнить следующие быстрые действия, которые позволят вам высвободить место в оперативной памяти.
Перезагрузите ваш компьютер
Первое, что вы можете сделать, чтобы попытаться освободить оперативную память, - это перезагрузить компьютер. Когда вы перезагружаете или выключаете компьютер, вся ваша оперативная память (сохраненные данные) будет стерта, а программы будут перезагружены. Это потенциально может очистить некоторые процессы и программы, которые работают в фоновом режиме и используют вашу оперативную память.
Обновите ваше ПО
Очень важно, чтобы на вашем компьютере использовались самые последние версии программного обеспечения и установленных приложений. Более старые версии программного обеспечения и приложений могут занимать больше памяти для обработки, что приводит к замедлению работы компьютера.
Попробуйте другой браузер
Что еще вы можете попробовать - это использовать другой браузер, так как некоторые из них, как известно, используют больше данных, чем другие. Попробуйте использовать, например, Chrome или Firefox, которые обычно являются хорошими браузерами с точки зрения потребления оперативной памяти.
Очистите ваш кэш
Если вам все еще не хватает оперативной памяти, следующий шаг – это попытаться очистить свой кэш (скешированные данные). Иногда ваш кэш может занимать много места, потому что он использует оперативную память. Кэш хранит информацию, которую ваш компьютер использует для перезагрузки страниц, которые он открывал ранее, чтобы не загружать их снова. Это может сэкономить вам время при просмотре, но если вам не хватает оперативной памяти, то кэшем вы можете пожертвовать без проблем.
Удалите расширения браузера
Наверняка, для упрощения ряда операций вы устанавливали в своем браузере дополнительные расширения. Однако они также требуют постоянного использования оперативной памяти, поэтому можно попробовать отключить или даже удалить эти расширения и дополнения к браузеру.
5 способов, как высвободить ОЗУ в Windows 10
Если вы все еще испытываете проблемы с чрезмерным использованием оперативной памяти, то, возможно, у вас слишком много лишних программ и приложений, о которых вы даже не знаете. Попробуйте пять способов ниже, чтобы высвободить оперативную память на компьютере с Windows 10.
1. Проверьте память и очистите процессы
Вы должны следить за использованием оперативной памяти вашего компьютера, чтобы не истощить ее запас прежде, чем она действительно потребуется вам для решения важных задач. Чтобы контролировать память вашего компьютера, вы можете перейти в Диспетчер задач для проверки процессов. Именно здесь вы сможете увидеть, какие программы запущены и сколько памяти они потребляют.
Чтобы проверить память вашего компьютера, выполните следующие действия:
1. Нажмите на клавиатуре одновременно клавиши Ctrl+Alt+Del и выберите Диспетчер задач.
2. Выберите закладку «Процессы».
3. Нажмите на названии столбца «Память», чтобы отсортировать процессы по объему используемой памяти.
Теперь вы можете видеть, какие из ваших программ требуют больше всего памяти на вашем компьютере. Если вы обнаружите какой-то подозрительный процесс, который «пожирает» много вашей памяти, вы можете остановить его, а также удалить соответствующие программы, которые вам не нужны или не используются. Но! Если вы не чувствуете себя уверенным в данном вопросе, то лучше обратиться к специалистам.
2. Отключить из автозагрузки те программы, которые вам не нужны
Если вы используете свой компьютер в течение нескольких лет, то вы, вероятно, скачали изрядное количество программ, про которые вы либо забыли, либо больше не используете их. После того, как закладка «Процессы» покажет вам, какие программы потребляют вашу память, то, возможно, вы захотите перейти к настройкам автозагрузки, чтобы удалить из нее те программы, которые вам больше не нужны.
Чтобы отключить автозагрузку программ, выполните следующие действия:
1. Выберите закладку «Автозагрузка» в Диспетчере задач.
2. Нажмите «Влияние на запуск», чтобы отсортировать программы по степени использования.
3. Нажмите правой кнопкой мыши, чтобы отключить любые ненужные вам программы.
Автозагружаемые программы – это те программы, которые активируются при загрузке вашего компьютера. Когда эти программы запускаются, каждая из них в фоновом режиме без вашего согласия потребляет определенный объем оперативной памяти. И хотя этот объем может быть не очень большой, но суммарно с другими программами и со временем это значение может возрасти. Убедитесь, что автозапуск всех ненужных программ отключен или такие программы вовсе удалены.
3. Остановите работу фоновых приложений
Следующие элементы, которые могут потреблять вашу оперативную память, - это ваши приложения, настроенные на автоматический запуск в фоновом режиме. Возможно, вы использовали свой компьютер в течение многих лет, прежде чем заметили, что некоторые из таких приложений потребляют вашу оперативную память. Такие приложения могут быть «сожрать» вашу память, батарею устройства и снизить производительность работы компьютера.
Чтобы остановить фоновые приложения:
1. Перейдите к настройкам компьютера.
2. Нажмите на раздел «Конфиденциальность».
3. Прокрутите вниз панель слева до «Фоновые приложения»
4. Отключите все приложения, которые вы не используете.
Часто приложения автоматически настроены для работы в фоновом режиме на вашем устройстве. Это позволяет им автоматически отображать уведомления и обновлять свое программное обеспечение. Отключив фоновой режим работы у приложений, которые вы не используете, вы можете сэкономить оперативную память.
4. Очищайте файл подкачки при завершении работы
Когда вы перезагружаете компьютер, ваши файлы подкачки не очищаются и не сбрасываются, потому что, в отличие от оперативной памяти, они хранятся на жестком диске. Таким образом, когда оперативная память получает сохраненные с различных страниц сайтов файлы, они не очищаются автоматически при выключении компьютера.
Очистка файлов подкачки на вашем жестком диске очистит все, что сохранила на жесткий диск ваша оперативная память, и поможет сохранить высокую производительность вашего компьютера. Вы можете настроить работу компьютера так, чтобы файлы подкачки удалялись автоматически при выключении компьютера, подобно ситуации с оперативной памяти. Это можно сделать в Редакторе Реестре:
1. Наберите «Редактор реестра» в строке поиска в стартовом меню
3. Слева прокрутите и выберите «HKEY_LOCAL_MACHINE»
4. Прокрутите ниже и выберите «SYSTEM»
5. Затем выберите «CurrentControlSet»
6. Найдите и выберите «Control»
7. Прокрутите и выберите «Session Manager»
8. Найдите и выберите «Memory Management»
9. Выберите «ClearPageFileAtShutdown»
10. Введите число «1» в качестве значения и нажмите OK.
5. Уберите визуальные эффекты
С улучшением технологий появляется гораздо больше возможностей для компьютерных эффектов и визуальных эффектов. Например, вы можете отключить анимацию для приложений и значков, которая также использует оперативную память для ненужных эффектов. Если вам кажется, что у вас заканчивается оперативная память, но при этом есть некоторые эффекты, от которых вы можете временно отказаться, пока не хватает памяти, то лучше отключите их.
Чтобы получить доступ к визуальным эффектам на вашем компьютере, выполните следующие действия:
1. Откройте Проводник.
2. В панели слева нажмите правой кнопкой мыши на «Этот компьютер», чтобы выбрать свойства.
3. Нажмите слева «Дополнительные параметры системы»
4. Выберите закладку «Дополнительно».
5. Перейдите к настройкам в разделе «Быстродействие»
6. Измените на «Обеспечить наилучшее быстродействие»
Данный параметр отключит все анимированные функции на вашем компьютере. Это позволит вам выделить больше оперативной памяти, но значительно ограничит эстетику вашего компьютера. Но на той же вкладке вы всегда можете настроить, какие визуальные эффекты ваш компьютер будет выполнять в соответствии с вашими предпочтениями.
5 способов высвободить ОЗУ на компьютере с Mac
Для пользователей Mac существует множество удобных инструментов для мониторинга и высвобождения оперативной памяти на компьютере.
1. Настройте Finder
При открытии нового окна в finder все данные, отображаемые в каждом окне, сохраняются в оперативной памяти. Настройка параметров finder позволяет вам открывать папки не в новых окнах, а на вкладках.
Чтобы открыть настройки вашего Finder:
1. Нажмите «Finder» в левом верхнем углу экрана.
2. Нажмите правой кнопкой мыши и в выпадающем меню выберите «Preferences».
3. Нажмите на опции «Open folders in tabs instead of new windows», чтобы открывать папки на вкладках, а не в новых окнах.
Существует еще один способ очистить оперативную память, объединив окна в вашем Finder. Вместо этого в левом верхнем меню выберите «Window», а не «Finder». Далее выберите «Merge All Windows», чтобы все ваши окна Finder открывались в одном окне. Это позволит вам сэкономить на использовании оперативной памяти, а также убрать лишнее с вашего рабочего стола.
2. Проверьте монитор активности Activity Monitor
Чтобы отслеживать использование оперативной памяти на Mac, вы можете проверить монитор активности, который показывает вам, сколько памяти используется и какие процессы ее используют. Используйте Монитор активности, чтобы определить, какие приложения больше всего потребляют оперативной памяти. Удалите те приложения, которые вы больше не используете.
Чтобы проверить монитор активности:
1. Найдите «Activity Monitor» в вашей панели поиска spotlight (Ctrl + Пробел).
2. Нажмите на закладке «Memory».
3. Удалите нежелательные приложения.
3. Проверьте использование процессора (CPU)
Вы также можете использовать приложение Activity Monitor для проверки работоспособности и уровня использования вашего процессора. CPU – это ваш центральный процессор, и он выполняет от компьютерных программ инструкции, которые хранятся в оперативной памяти.
Чтобы контролировать свой процессор, просто выберите вкладку «CPU». Именно здесь вы можете увидеть, какие приложения больше всего потребляют ресурсы процессора.
4. Почистите программы и приложения
Если вы хотите, чтобы ваша оперативная память использовалась эффективно, то вам нужно будет поддерживать свой компьютер в порядке. Загроможденный рабочий стол будет использовать оперативную память намного интенсивнее, потому что macOS рассматривает каждый значок рабочего стола как активное окно. Даже если вы не думаете, что можете организовать свои файлы, просто помещая все в одну общую папку, вы сможете высвободить много оперативной памяти.
5. Очистите дисковое пространство
Если вы обнаружите, что ваша оперативная память полностью заполнена, но вам нужно еще больше оперативной памяти, то вы можете использовать свободное пространство на диске вашего Mac, называемой виртуальной памятью. Это дополнительное хранилище находится на жестких дисках компьютера Mac, так что вы можете продолжать запускать приложения. Эта функция всегда включена, однако для использования виртуальной памяти вам нужно будет убедиться, что у вас есть достаточно свободного места для ее работы.
Дополнительные способы высвобождения ОЗУ на устройствах с Windows или Mac
Самое лучшее, что можно сделать, - это «играть на опережение», чтобы эффективно использовать оперативную память вашего компьютера не беспокоиться о высвобождении места на компьютере. Используйте перечисленные ниже дополнительные способы, чтобы высвободить вашу оперативную память.
Установите «очиститель» памяти
Если вы обнаружите, что у вас нет времени или вы просто не можете организовать свой компьютер, существуют приложения для очистки памяти, которые помогут вам вылечить ваш компьютер. Многие из таких программ имеют специальные функции для удаления приложений или расширений и позволяют пользователям управлять автозапуском своих программ.
Увеличьте объем ОЗУ
Вы всегда можете добавить на своем компьютере дополнительные планки памяти, чтобы увеличить объем оперативной памяти. Купить и добавить ОЗУ достаточно легко для настольного компьютера, но может быть затруднительно для ноутбуков. Убедитесь, что вы покупаете правильный тип и объем оперативной памяти для вашего компьютера, и будьте уверены в своих силах, что сможете правильно ее установить, иначе обратитесь к специалисту.
Проверьте на вирусы и вредоносные программы
Когда вы загружаете какие-либо программы или расширения на свой компьютер, существует вероятность того, что к ним может быть прикреплен вирус или другое вредоносное ПО. Как только на вашем компьютере появляется вредоносное ПО, оно может начать кражу как вашей информации, так и вашей памяти. Чтобы предотвратить попадание каких-либо вредоносных программ или вирусов, попробуйте использовать антивирус Panda для защиты вашего компьютера и памяти.
Сейчас самое время провести ревизию ваших файлов и приложений. Многие файлы, приложения и процессы на вашем компьютере занимают место в оперативной памяти без вашего ведома. Теперь вы знаете, как безопасно избавить ваш компьютер от этих неиспользуемых файлов и как освободить оперативную память, чтобы ваш компьютер работал более эффективно.
В оперативной памяти (RAM) компьютера хранятся все выполняемые на нём в реальном времени процессы, а также данные, обрабатываемые процессором. Физически она располагается на оперативном запоминающем устройстве (ОЗУ) и в так называемом файле подкачки (pagefile.sys), который представляет собой виртуальную память. Именно от ёмкости этих двух компонентов зависит то, сколько информации сможет одновременно обрабатывать ПК. Если общий объем запущенных процессов приближается к величине ёмкости RAM, то компьютер начинает тормозить и зависать.
Некоторые процессы, находясь в «спящем» состоянии, просто резервируют место на RAM, не выполняя никаких полезных функций, но при этом занимают место, которое могли бы использовать активные приложения. Для очистки оперативной памяти от подобных элементов существуют специализированные программы. Ниже мы поговорим о самых популярных из них.
Ram Cleaner
Приложение Ram Cleaner в свое время являлось одним из самых популярных платных инструментов для очистки оперативной памяти компьютера. Успехом оно было обязано своей эффективности в сочетании с простотой в управлении и минимализмом, что импонировало многим пользователям.
К сожалению, с 2004 года приложение не поддерживается разработчиками, а вследствие этого нет гарантии, что оно будет работать столь же эффективно и корректно на операционных системах, выпущенных после указанного времени.
RAM Manager
Приложение RAM Manager представляет собой не только средство для очистки оперативной памяти ПК, но и менеджер процессов, который по некоторым возможностям превосходит стандартный «Диспетчер задач» Виндовс.
К сожалению, как и предыдущая программа, RAM Manager является заброшенным проектом, который не обновлялся с 2008 года, а поэтому он не оптимизирован для современных операционных систем. Тем не менее, данное приложение все ещё пользуется определенной популярностью среди пользователей.
FAST Defrag Freeware
FAST Defrag Freeware – очень мощное приложение для управления оперативной памятью компьютера. Кроме функции очистки, оно включает в свой инструментарий менеджер задач, средства для удаления программ, управления автозагрузкой, оптимизации Виндовс, отображения информации о выбранной программе, а также предоставляет доступ ко множеству внутренних утилит операционной системы. А свою основную задачу оно выполняет прямо из трея.
Но, как и две предыдущие программы, FAST Defrag Freeware представляет собой закрытый разработчиками проект, не обновлявшийся с 2004 года, что вызывает те же проблемы, которые уже были описаны выше.
RAM Booster
Довольно эффективным инструментом для очистки ОЗУ является RAM Booster. Главная его дополнительная функция – это возможность удаления данных из буфера обмена. Кроме того, с помощью одного из пунктов меню программы выполняется перезагрузка компьютера. Но вообще, она довольно проста в управлении и основную свою задачу выполняет автоматически из трея.
Данное приложение, как и предыдущие программы, относился к категории закрытых проектов. В частности, RAM Booster не обновлялся с 2005 года. К тому же в его интерфейсе отсутствует русский язык.
RamSmash
RamSmash является типичной программой для очистки оперативной памяти. Отличительной её чертой является углубленное отображение статистической информации о загруженности RAM. Кроме того, нельзя не отметить довольно привлекательный интерфейс.
С 2014 года программа не обновляется, так как разработчики вместе с ребрендингом собственного наименования, начали развивать новую ветку данного продукта, которая получила название SuperRam.
SuperRam
Приложение SuperRam является продуктом, который получился вследствие развития проекта RamSmash. В отличие от всех программных инструментов, которые мы описали выше, данное средство для очистки оперативной памяти в настоящее время является актуальным и регулярно обновляемым разработчиками. Впрочем, эта же характеристика будет относиться и к тем программам, о которых пойдет речь ниже.
К сожалению, в отличие от RamSmash, более современная версия этой программы SuperRam пока не русифицирована, а поэтому её интерфейс исполнен на английском языке. К недостаткам можно также отнести возможное зависание компьютера во время самого процесса очистки ОЗУ.
WinUtilities Memory Optimizer
Довольно простым, удобным в управлении и в то же время визуально привлекательно оформленным средством для чистки ОЗУ является WinUtilities Memory Optimizer. Кроме предоставления информации о нагрузке на RAM, оно предоставляет аналогичные данные о центральном процессоре.
Как и предыдущей программе, WinUtilities Memory Optimizer свойственны зависания во время процедуры чистки ОЗУ. К минусам также можно отнести отсутствие русскоязычного интерфейса.
Clean Mem
Программа Clean Mem обладает довольно ограниченным набором функций, но свою основную задачу по ручной и автоматической очистке оперативной памяти, а также по мониторингу состояния RAM она выполняет отлично. К дополнительному функционалу можно отнести разве что возможность управлять отдельными процессами.
Главными недостатками Clean Mem являются отсутствие русскоязычного интерфейса, а также тот факт, что корректно работать он может только при включенном планировщике задач Windows.
Mem Reduct
Следующей популярной, современной программой для очистки ОЗУ является Mem Reduct. Это средство отличается простотой и минимализмом. Кроме функций очистки оперативной памяти и отображения её состояния в реальном времени, более никакими дополнительными возможностями данный продукт не обладает. Впрочем, как раз такая простота и привлекает многих пользователей.
К сожалению, как и у многих других аналогичных программ, при использовании Mem Reduct на маломощных компьютерах наблюдается зависание во время процесса чистки.
Mz Ram Booster
Довольно эффективным приложением, помогающим очистить RAM компьютера, является Mz Ram Booster. С его помощью можно оптимизировать не только нагрузку на оперативную память, но и на центральный процессор, а также получить развернутую информацию о работе этих двух компонентов. Нельзя не отметить очень ответственный подход разработчиков к визуальному оформлению программы. Предусмотрена даже возможность смены нескольких тем.
К «минусам» приложения можно отнести разве что отсутствие русификации. Но благодаря интуитивно понятному интерфейсу данный недостаток не является критическим.
Как видим, существует довольно большой набор приложений для очистки оперативной памяти компьютера. Каждый пользователь может подобрать вариант на свой вкус. Тут представлены как инструменты с минимальным набором возможностей, так и средства, которые имеют довольно широкий дополнительный функционал. К тому же некоторые юзеры по привычке предпочитают использовать устаревшие, но уже хорошо зарекомендовавшие себя программы, не доверяя более новым.
Мы рады, что смогли помочь Вам в решении проблемы.
Отблагодарите автора, поделитесь статьей в социальных сетях.
Опишите, что у вас не получилось. Наши специалисты постараются ответить максимально быстро.
Читайте также: