Letysite.ru

IT Новости с интернет пространства
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Управление памятью linux

Управление памятью в Linux

Данная тема, на первый взгляд, не является важной для системного администрирования. А скорее более полезна тем, кто занимается разработкой, отладкой или тестированием программного обеспечения (ПО) под Linux. Однако, понимание того, как устроена и функционирует система управления памятью в Linux (даже на базовом уровне). Для любого системного администратора также может быть полезным. В первую очередь для анализа производительности системы. А также для поиска решений для её увеличения и/или оптимизации.

Как устроена память в Linux?

Базовой единицей в организации памяти для систем UNIX/Linux является страница памяти. Обладающая размером от 4 Кбайт, которому соответствует объём физического пространства в оперативной или виртуальной (область подкачки на диске или другом устройстве хранения) памяти. При запуске процессов, они запрашивают у системы (т. е. у ядра посредством соответствующих системных вызовов) память для своей работы. А в ответ на это ядро выделяет для них достаточное количество страниц памяти. Виртуальная память или как её ещё называют, «резервное ЗУ» (резервное запоминающее устройство) для страниц памяти. Которые содержат, к примеру, исходный текст исполняемого приложения, представляют собой обычные исполняемые файлы на диске. Равно как и для других файлов данных резервным ЗУ являются сами файлы. Информация о том как взаимосвязаны страницы физической и виртуальной памяти хранится в соответствующих таблицах страниц памяти.

Для работы с памятью в Linux (как и в других UNIX-подобных системах) характерно такое явление как «страничный обмен» (paging). Оно заключается в том, что ядро выделяет процессам столько памяти, сколько им необходимо. В том смысле, чтобы её (памяти) всегда хватало. Это достигается за счёт расширения физической памяти за счёт виртуальной, т. е. «подкачки». Поскольку выполнение процессов должно происходить в реальной физической памяти. То ядро постоянно перемещает страницы памяти процессов между физической и виртуальной памятью. Забегая вперёд, следует отметить, что в виртуальной памяти хранятся «неактивные» страницы. Которые не задействованы процессом в данный момент, но необходимые ему для полноценной работы впоследствии.

Основные принципы управления памятью в Linux

Первое, на что следует обратить внимание, это то, что ядро старается управлять памятью таким образом, чтобы недавно используемые процессом страницы находились в физической памяти. И в свою очередь, «неактивные» или редко используемые страницы перемещаются и хранятся в виртуальной памяти в области «подкачки». Такой механизм распределения памяти называется LRU (least recently used) — замещение наиболее редко используемых страниц.

Вторым важнейшим аспектом в работе памяти является использование кеш-буфера страниц. Это вытекает из работы алгоритма LRU, который довольно сложен в своей реализации. Поскольку следить за всеми обращениями к страницам — это в некоторых случаях, довольно ощутимые потери в производительности системы. Использование же страничного кеш-буфера куда проще в своей реализации при тех же самых результатах. К тому же данный подход имеет огромный модернизационный потенциал (в отличие от LRU) и алгоритмы анализа содержимого кеш-буфера (для определения, какие страницы должны быть перемещены из виртуальной памяти) постоянно совершенствуются. Что заметно сказывается на производительности и эффективности управления памятью.

Когда процессу не хватает памяти, то ядро начинает искать «занятые» страницы. Которые можно использовать для «голодающего» процесса. Обычно такими страницами являются те, что давно не были использованы. Ядро проверяет их на предмет модификации каким-либо процессом. Для этого существуют определённые признаки, при последнем обращении и если изменения были, то такие страницы помечаются ядром как «грязные». Т. е. такие, которые ещё нужны процессам. Для повторного использования памяти такие страницы сначала обязательно переносятся в виртуальную память. Все же остальные страницы являются «чистыми». И поэтому ядро их использует для предоставления другим или «голодающим» процессам.

Особенности управления памятью в Linux

Когда происходит обращение к страницам памяти, которые некоторое или долгое время не использовалис, т. е. к «неактивным» страницам. То ядро выполняет с ними несколько важных задач:

  • возвращает ссылки на эти страницы в соответствующей таблице страниц;
  • сбрасывает в нулевое значение время «неиспользования» этих страниц;
  • помечает эти страницы как «активные».

Со страницами, находящимися в виртуальной памяти не всё так однозначно. Дело в том, что для того, чтобы «активизировать» такие страницы, они должны быть предварительно прочитаны с диска.

Системное ядро комплектуется специализированными модулями. Которые содержат алгоритмы и даже целые технологии. С помощью которых система довольно эффективно «предсказывает», сколько может потребоваться памяти при разной степени активности и загруженности процессов. Эти алгоритмы имеют своей целью обеспечение процессов свободной памятью с максимальной эффективностью. Т. е. так, чтобы процессам как можно реже приходилось простаивать в «ожидании» выгрузки очередной страницы в свободную память. Таким образом, наблюдая за состоянием страничного обмена во время рабочей нагрузки системы, можно делать выводы о том, нужна ли ей дополнительная память. Если страничный обмен интенсивный — то однозначно следует установить дополнительные модули ОЗУ.

Если же происходит так, что процессам не хватает ни реальной физической, ни виртуальной памяти. Т. е. когда память полностью исчерпана, то система начинает завершать (а точнее уничтожать) целые процессы. Либо запрещает создание новых. Конечно в этом случае в первую очередь уничтожаются наиболее «безболезненные» для системы процессы. Однако в таких случаях даже «на глаз» и по собственным ощущениям видно что она большую часть времени тратит на управление памятью, а не на выполнение рабочих задач.

В Linux можно настроить параметр, который задаёт, насколько быстро ядро должно «отбирать»страницы памяти у процессов. Которым они менее нужны для процессов, которым они на данный момент необходимы. Этот параметр содержится в файле /proc/sys/vm/swappiness и по-умолчанию равен 60. Если задать его меньшим значением (например 0). То ядро будет забирать страницы процесса в самую последнюю очередь. Используя вместо этого любые другие варианты. Если это значение в пределах между 60 и 100. То страницы будут отбираться у процессов с более высокой вероятностью. Вариант с изменением данного параметра на самом деле говорит о том, что необходимо либо снизить нагрузку на систему. Адаптировав её для других менее производительных задач, либо увеличить объём ОЗУ.

Заключение

В заключение следует отметить, что схема работы и управления с памятью в Linux не так уж и сложна. Гораздо более сложнее специфические задачи. Такие как анализ содержимого кеш-буфера страниц и его интеллектуальное использование. Но это уже работа программистов и разработчиков. В свою очередь понимание основ управления памятью помогает лучше распоряжаться ресурсами системы. Что для системных администраторов очень важно.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Управление памятью в Linux

Я думаю, что обычно у каждого пользователя Linux рано или поздно возникает следующий вопрос, задаваемый при администрировании рабочей станции или сервера — «Почему в Linux используется вся моя оперативная память, хотя никакой большой работы не выполняется? «. К нему сегодня я добавлю еще один вопрос, который, я уверен, обычен для многих системных администраторов Linux — «Почему команда free показывает память swap и почему у меня так много свободной оперативной памяти?», так что сегодняшнее мое исследование SwapCached, которое я представляю вам, может оказаться полезным, либо, по крайней мере, ознакомит, как я надеюсь, с информацией об управлении памятью в системе Linux.

В Linux применяется следующее основное правило: неиспользуемая страница оперативной памяти считается потерянной памятью. Оперативная память тратится не только для данных, используемых прикладными приложениями. В ней также хранятся данные для самого ядра и, самое главное, в эту память могут отображаться данные, хранящиеся на жестком диске, что используется для супер-быстрого к ним доступа — команда top указывает об этом в столбцах «buffers/cache» («буферы / кэш»), «disk cache» («дисковый кэш)» или «cached» («кэшировано»). Кэшированная память по сути свободна, поскольку ее можно быстро освободить в случае, если работающей (или только что запущенной) программе потребуется память.

Сохранение кэша означает, что если кому-нибудь еще раз потребуются те же самые данные, то есть большая вероятность, что они все еще будут находиться в кэше в оперативной памяти.

Поэтому первое, чем можно воспользоваться в вашей системе, это команда free , которая предоставит вам первоначальную информацию о том, как используется ваша оперативная память.

Ниже приведены данные, выдаваемые на моем старом ноутбуке с системой Xubuntu:

В строке -/+ buffers/cache показывается, сколько памяти используется и сколько памяти свободно с точки зрения ее использования в приложениях. В этом примере приложениями уже используется 972 Мб памяти и еще 534 МБ памяти могут быть использованы.

Вообще говоря, если используется хотя бы немного памяти подкачки swap, то использование памяти вообще не повлияет на производительность системы.

Но если вы хотите получить более подробную информацию о вашей памяти, то вы должны проверить файл /proc/meminfo; в моей системе Xubuntu с ядром 3.2.0-25-generic результат будет следующим:

Что означает MemTotal (Всего памяти) и MemFree (Свободная память), понятно для всех; остальные значения поясняются дальше:

Cached

Страничный кэш в системе Linux («Cached:» в meminfo) является в большинстве систем самым крупным потребителем памяти. Каждый раз, когда вы выполняете операцию чтения read () из файла, расположенного на диске, данные считываются в память и помещаются в страничный кэш. После того, как операция read() завершается, ядро может просто выбросить страницу памяти, так как она не используется. Однако, если вы второй раз выполняете операцию чтения той же самой части файла, данные будут считываться непосредственно из памяти и обращения к диску не будет. Это невероятно ускоряет работу и, поэтому, в Linux так интенсивно используется кэширование страниц: ставка делается на то, что если вы обратились к некоторой странице дисковой памяти, то вскоре вы обратитесь к ней снова.

dentry/inode caches

Каждый раз, когда вы в файловой системе выполняете операцию «ls’» (или любую другую операцию: open(), stat() и т.д.), ядру требуются данные, которые находятся на диске. Ядро анализирует эти данные, находящиеся на диске, и помещает его в некоторых структуры данных, независимые от файловой системы, с тем, чтобы они могли в различных файловых системах обрабатываться одним и тем же образом. Таким же самым образом, как кэширование страниц в приведенных выше примерах, ядро может после того, как будет завершена команда «ls», стереть эти структуры. Тем не менее, делается такое же предположение, как и раньше: если вы однажды считали эти данные, вы обязательно прочитаете их еще раз. Ядро хранит эту информацию в нескольких местах «кэша», которые называются кэш памятью dentry и inode. Кэш память dentries являются общей для всех файловых систем, но каждая файловая система имеет свой собственный кэш inodes.

Читать еще:  Linux скачать файл

Эта оперативная память является в meminfo составной частью «Slab:»

Вы можете просмотреть различную кэш память и узнать ее размеры с помощью следующей команды:

Buffer Cache

Кэш буфера («Buffers:» в meminfo) является близким родственником кэш памяти dentry/inode. Данные dentries и inodes, размещаемые в памяти, представляют собой описание структур на диске, но располагаются они по-разному. Это, возможно, связано с тем, что у нас в копии, расположенной в памяти, используется такая структура, как указатель, но на диске ее нет. Может также случиться, что на диске байты будут располагаться не в том порядке, как это нужно процессору.

Отображение памяти в команде top: VIRT, RES и SHR

Если вы запускаете команду top , то три строки будут описывать к использованию памяти. Вы должны понимать их значение с тем, чтобы понять, сколько памяти требуется вашему серверу.

VIRT является сокращением от virtual size of a process (виртуальный размер процесса) и представляет собой общий объем используемой памяти: памяти, отображаемой самой в себя (например, памяти видеокарты для сервера X), файлов на диске, которые отображаются в память (особенно это касается разделяемых библиотек) и памяти, разделяемой совместно с другими процессами. Значение VIRT указывает, сколько памяти в настоящий момент доступно программе.

RES является сокращением от resident size (размер резидентной части) и является точным указателем того, сколько в действительности потребляется процессом реальной физической памяти. (Что также соответствует значению, находящемуся непосредственно в колонке %MEM). Это значение практически всегда меньше, чем размер VIRT, т.к. большинство программ зависит от библиотеки C.

SHR показывает, какая величина от значения VIRT является в действительности разделяемой (по памяти или за счет использования библиотек). В случае библиотек, это не обязательно означает, что вся библиотека находится в резидентной памяти. Например, если программа использует только несколько функций библиотеки, то при отображении в память будет использована вся библиотека, что будет учтено в значениях VIRT и SHR, но, на самом деле, будет загружена часть библиотеки, содержащая используемые функции, и это будет учтено в значении RES.

Подкачка памяти — swap

Теперь мы видим некоторую информацию о нашей оперативной памяти, но что происходит, когда больше нет свободной оперативной памяти? Если у меня нет свободной памяти, а мне нужна память для страничного кэширования, кэширования inode или кэширования dentry, то где я ее могу получить?

Прежде всего, ядро пытается не допустить, чтобы у вас значение свободной оперативной памяти приближалось к 0 байтов. Это связано с тем, что когда нужно освободить оперативную память, то обычно требуется выделить немного больше памяти. Это обусловлено тем, что нашему ядру требуется своего рода «рабочее пространство» для выполнения своих действий, и поэтому, если размер свободной оперативной памяти становится равным нулю, ядро ничего больше сделать не сможет.

На основании общего объема оперативной памяти и соотношения ее различных типов (память high/low), ядро эвристически определяет то количество памяти в качестве рабочего пространства, при котором оно чувствует себя комфортно. Когда эта величина достигается, ядро начинает возвращать память для других различных задач, описанных выше. Ядро может вернуть себе память из любой из этих задач.

Однако, есть другой потребитель памяти, о котором мы, возможно, уже забыли: данные пользовательских приложений.

Как только ядро принимает решение, что ему не требуется получать память из каких-либо других источников, которые мы описывали ранее, оно запускает память подкачки swap. В ходе этого процесса оно получает данные пользовательских приложений и записывает их в специальное место (или места) на диске. Обратите внимание, что это происходит не только тогда, когда оперативная память близка к заполнению, ядро может принять решение перенести в память swap также данные, находящиеся в оперативной памяти, если они некоторое время не использовались (смотрите раздел «Подкачка памяти»).

По этой причине, даже система с огромным количеством оперативной памяти (даже если ее правильно настроить) может использовать память подкачки swap. Есть много страниц памяти, в которых находятся данные пользовательских приложений, но эти страницы используются редко. Все это является причиной, чтобы перенести их в раздел swap и использовать оперативную память для других целей.

Вы можете с помощью команды free проверить, используется ли память swap; для примера, который я уже использовал выше, в последней строке выдаваемых данных показывается информация о размере памяти swap:

Мы видим, что на этом компьютере уже используется 24 мегабайта памяти swap и для использования доступно еще 462 Мб.

Таким образом, сам факт использования памяти swap не является доказательством того, что в системе при ее текущей рабочей нагрузке слишком мало оперативной памяти. Лучший способ это определить с помощью команды vmstat — если вы увидите, что много страниц памяти swap перемещаются на диск и обратно, то это означает, что память swap используется активно, что система «пробуксовывает» или что ей нужна новая оперативная память поскольку это ускорит подкачку данных приложений.

На моем ноутбуке Gentoo, когда он простаивает, это выглядит следующим образом:

Обратите внимание на то, что в выходных данных команды free у вас есть только 2 значения, относящихся к памяти swap: free (свободная память) и used (используемая память), но для памяти подкачки swap также есть еще одно важное значение: Swap cache (показатель кэширования памяти подкачки).

Кэширование памяти swap (Swap Cach)

Кеширование памяти swap по сути очень похоже на страничное кеширование. Страница данных пользовательского приложения, записываемая на диск, очень похожа на страницу данных файла, находящуюся на диске. Каждый раз, когда страница считывается из файла подкачки («si» в vmstat), она помещается в кэш подкачки. Так же, как страничное кэширование, все это выполняется ядром. Ядро решает, нужно ли вернуть обратно на диск конкретную страницу. Если в этом возникнет необходимость, то можно проверить, есть ли копия этой страницы на диске и можно просто выбросить страницу из памяти. Это избавит нас от затрат на переписывание страницы на диск.

Кэширование памяти swap действительно полезно только когда мы читаем данные из памяти swap и никогда в нее не делаем записи. Если мы выполняем запись на страницу, то копия на диске не будет соответствовать копии, находящейся в памяти. Если это случится, то мы должны произвести запись страницы на диск точно также, как мы делали это первый раз. Несмотря на то, что затраты на сохранение всей страницы больше, чем затраты на запись небольшого измененного кусочка, система будет работать лучше.

Поэтому, чтобы узнать, что память swap действительно используется, мы должны из значения SwapUsed вычесть значение SwapCached, вы можете найти эту информацию в /proc/meminfo.

Подкачка памяти

Когда приложению нужна память, а вся оперативная память полностью занята, то в распоряжении ядра есть два способа освободить память: оно может либо уменьшить размер дискового кэша в оперативной памяти, убирая устаревшие данные, либо оно может сбросить на диск в swap раздел несколько достаточно редко используемых порций (страниц) программы. Трудно предсказать, какой из способов будет более эффективным. Ядро, исходя из недавней истории действий в системе, делает попытку приблизительно отгадать на данный момент эффективность каждого из этих двух методов.

До ядер версии 2.6 у пользователя не было возможности влиять на эти оценки, так что могла возникнуть ситуации, когда ядро часто делало неправильный выбор, что приводило к пробуксовыванию и низкой производительности. В версии 2.6 ситуация с подкачкой памяти была изменена.

Подкачке памяти назначается значение от 0 до 100, которое изменяет баланс между подкачкой памяти приложений и освобождением кэш памяти. При значении 100 ядро всегда предпочтет найти неактивные страницы и сбросить их на диск в раздел swap; в других случаях этот сброс будет осуществляться в зависимости от того, сколько памяти занимает приложение и насколько трудно выпонять кэширование при поиске и удалении неактивных элементов.

По умолчанию для этого устанавливается значение 60. Значение 0 дает нечто близкое к старому поведению, когда приложения, которым нужна память, заставляли немного уменьшить размер кэша оперативной памяти. Для ноутбуков, для которых предпочтительно иметь диски с меньшей скоростью вращения, рекомендуется использовать значение 20 или меньше.

Заключение

В этой статье я поместил информацию, которая была мне полезной в моей работе в качестве системного администратора, и я надеюсь, что она может оказаться полезной и для вас.

Управление памятью в Linux

Оригинал: «Linux memory management»
Автор: Riccardo Capecchi
Дата публикации: June 22, 2012
Перевод: Н.Ромоданов
Дата перевода: август 2012 г.

Я думаю, что обычно у каждого пользователя Linux рано или поздно возникает следующий вопрос, задаваемый при администрировании рабочей станции или сервера — «Почему в Linux используется вся моя оперативная память, хотя никакой большой работы не выполняется? «. К нему сегодня я добавлю еще один вопрос, который, я уверен, обычен для многих системных администраторов Linux — «Почему команда free показывает память swap и почему у меня так много свободной оперативной памяти?», так что сегодняшнее мое исследование SwapCached, которое я представляю вам, может оказаться полезным, либо, по крайней мере, ознакомит, как я надеюсь, с информацией об управлении памятью в системе Linux.

В Linux применяется следующее основное правило: неиспользуемая страница оперативной памяти считается потерянной памятью. Оперативная память тратится не только для данных, используемых прикладными приложениями. В ней также хранятся данные для самого ядра и, самое главное, в эту память могут отображаться данные, хранящиеся на жестком диске, что используется для супер-быстрого к ним доступа — команда top указывает об этом в столбцах «buffers/cache» («буферы / кэш»), «disk cache» («дисковый кэш)» или «cached» («кэшировано»). Кэшированная память по сути свободна, поскольку ее можно быстро освободить в случае, если работающей (или только что запущенной) программе потребуется память.

Сохранение кэша означает, что если кому-нибудь еще раз потребуются те же самые данные, то есть большая вероятность, что они все еще будут находиться в кэше в оперативной памяти.

Читать еще:  Linux mount smb

Поэтому первое, чем можно воспользоваться в вашей системе, это команда free, которая предоставит вам первоначальную информацию о том, как используется ваша оперативная память.

Ниже приведены данные, выдаваемые на моем старом ноутбуке с системой Xubuntu:

В строке -/+ buffers/cache показывается, сколько памяти используется и сколько памяти свободно с точки зрения ее использования в приложениях. В этом примере приложениями уже используется 972 Мб памяти и еще 534 МБ памяти могут быть использованы.

Вообще говоря, если используется хотя бы немного памяти подкачки swap, то использование памяти вообще не повлияет на производительность системы.

Но если вы хотите получить более подробную информацию о вашей памяти, то вы должны проверить файл /proc/meminfo; в моей системе Xubuntu с ядром 3.2.0-25-generic результат будет следующим:

Что означает MemTotal (Всего памяти) и MemFree (Свободная память), понятно для всех; остальные значения поясняются дальше:

Cached

Страничный кэш в системе Linux («Cached:» в meminfo) является в большинстве систем самым крупным потребителем памяти. Каждый раз, когда вы выполняете операцию чтения read () из файла, расположенного на диске, данные считываются в память и помещаются в страничный кэш. После того, как операция read() завершается, ядро может просто выбросить страницу памяти, так как она не используется. Однако, если вы второй раз выполняете операцию чтения той же самой части файла, данные будут считываться непосредственно из памяти и обращения к диску не будет. Это невероятно ускоряет работу и, поэтому, в Linux так интенсивно используется кэширование страниц: ставка делается на то, что если вы обратились к некоторой странице дисковой памяти, то вскоре вы обратитесь к ней снова.

dentry/inode caches

Каждый раз, когда вы в файловой системе выполняете операцию «ls»» (или любую другую операцию: open(), stat() и т.д.), ядру требуются данные, которые находятся на диске. Ядро анализирует эти данные, находящиеся на диске, и помещает его в некоторых структуры данных, независимые от файловой системы, с тем, чтобы они могли в различных файловых системах обрабатываться одним и тем же образом. Таким же самым образом, как кэширование страниц в приведенных выше примерах, ядро может после того, как будет завершена команда «ls», стереть эти структуры. Тем не менее, делается такое же предположение, как и раньше: если вы однажды считали эти данные, вы обязательно прочитаете их еще раз. Ядро хранит эту информацию в нескольких местах «кэша», которые называются кэш памятью dentry и inode. Кэш память dentries являются общей для всех файловых систем, но каждая файловая система имеет свой собственный кэш inodes.

Эта оперативная память является в meminfo составной частью «Slab:»

Вы можете просмотреть различную кэш память и узнать ее размеры с помощью следующей команды:

Buffer Cache

Кэш буфера («Buffers:» в meminfo) является близким родственником кэш памяти dentry/inode. Данные dentries и inodes, размещаемые в памяти, представляют собой описание структур на диске, но располагаются они по-разному. Это, возможно, связано с тем, что у нас в копии, расположенной в памяти, используется такая структура, как указатель, но на диске ее нет. Может также случиться, что на диске байты будут располагаться не в том порядке, как это нужно процессору.

Отображение памяти в команде top: VIRT, RES и SHR

Если вы запускаете команду top, то три строки будут описывать к использованию памяти. Вы должны понимать их значение с тем, чтобы понять, сколько памяти требуется вашему серверу.

VIRT является сокращением от virtual size of a process (виртуальный размер процесса) и представляет собой общий объем используемой памяти: памяти, отображаемой самой в себя (например, памяти видеокарты для сервера X), файлов на диске, которые отображаются в память (особенно это касается разделяемых библиотек) и памяти, разделяемой совместно с другими процессами. Значение VIRT указывает, сколько памяти в настоящий момент доступно программе.

RES является сокращением от resident size (размер резидентной части) и является точным указателем того, сколько в действительности потребляется процессом реальной физической памяти. (Что также соответствует значению, находящемуся непосредственно в колонке %MEM). Это значение практически всегда меньше, чем размер VIRT, т.к. большинство программ зависит от библиотеки C.

SHR показывает, какая величина от значения VIRT является в действительности разделяемой (по памяти или за счет использования библиотек). В случае библиотек, это не обязательно означает, что вся библиотека находится в резидентной памяти. Например, если программа использует только несколько функций библиотеки, то при отображении в память будет использована вся библиотека, что будет учтено в значениях VIRT и SHR, но, на самом деле, будет загружена часть библиотеки, содержащая используемые функции, и это будет учтено в значении RES.

Подкачка памяти — swap

Теперь мы видим некоторую информацию о нашей оперативной памяти, но что происходит, когда больше нет свободной оперативной памяти? Если у меня нет свободной памяти, а мне нужна память для страничного кэширования, кэширования inode или кэширования dentry, то где я ее могу получить?

Прежде всего, ядро пытается не допустить, чтобы у вас значение свободной оперативной памяти приближалось к 0 байтов. Это связано с тем, что когда нужно освободить оперативную память, то обычно требуется выделить немного больше памяти. Это обусловлено тем, что нашему ядру требуется своего рода «рабочее пространство» для выполнения своих действий, и поэтому, если размер свободной оперативной памяти становится равным нулю, ядро ничего больше сделать не сможет.

На основании общего объема оперативной памяти и соотношения ее различных типов (память high/low), ядро эвристически определяет то количество памяти в качестве рабочего пространства, при котором оно чувствует себя комфортно. Когда эта величина достигается, ядро начинает возвращать память для других различных задач, описанных выше. Ядро может вернуть себе память из любой из этих задач.

Однако, есть другой потребитель памяти, о котором мы, возможно, уже забыли: данные пользовательских приложений.

Как только ядро принимает решение, что ему не требуется получать память из каких-либо других источников, которые мы описывали ранее, оно запускает память подкачки swap. В ходе этого процесса оно получает данные пользовательских приложений и записывает их в специальное место (или места) на диске. Обратите внимание, что это происходит не только тогда, когда оперативная память близка к заполнению, ядро может принять решение перенести в память swap также данные, находящиеся в оперативной памяти, если они некоторое время не использовались (смотрите раздел «Подкачка памяти»).

По этой причине, даже система с огромным количеством оперативной памяти (даже если ее правильно настроить) может использовать память подкачки swap. Есть много страниц памяти, в которых находятся данные пользовательских приложений, но эти страницы используются редко. Все это является причиной, чтобы перенести их в раздел swap и использовать оперативную память для других целей.

Вы можете с помощью команды free проверить, используется ли память swap; для примера, который я уже использовал выше, в последней строке выдаваемых данных показывается информация о размере памяти swap:

Мы видим, что на этом компьютере уже используется 24 мегабайта памяти swap и для использования доступно еще 462 Мб.

Таким образом, сам факт использования памяти swap не является доказательством того, что в системе при ее текущей рабочей нагрузке слишком мало оперативной памяти. Лучший способ это определить с помощью команды vmstat — если вы увидите, что много страниц памяти swap перемещаются на диск и обратно, то это означает, что память swap используется активно, что система «пробуксовывает» или что ей нужна новая оперативная память поскольку это ускорит подкачку данных приложений.

На моем ноутбуке Gentoo, когда он простаивает, это выглядит следующим образом:

Обратите внимание на то, что в выходных данных команды free у вас есть только 2 значения, относящихся к памяти swap: free (свободная память) и used (используемая память), но для памяти подкачки swap также есть еще одно важное значение: Swap cache (показатель кэширования памяти подкачки).

Кэширование памяти swap (Swap Cach)

Кеширование памяти swap по сути очень похоже на страничное кеширование. Страница данных пользовательского приложения, записываемая на диск, очень похожа на страницу данных файла, находящуюся на диске. Каждый раз, когда страница считывается из файла подкачки («si» в vmstat), она помещается в кэш подкачки. Так же, как страничное кэширование, все это выполняется ядром. Ядро решает, нужно ли вернуть обратно на диск конкретную страницу. Если в этом возникнет необходимость, то можно проверить, есть ли копия этой страницы на диске и можно просто выбросить страницу из памяти. Это избавит нас от затрат на переписывание страницы на диск.

Кэширование памяти swap действительно полезно только когда мы читаем данные из памяти swap и никогда в нее не делаем записи. Если мы выполняем запись на страницу, то копия на диске не будет соответствовать копии, находящейся в памяти. Если это случится, то мы должны произвести запись страницы на диск точно также, как мы делали это первый раз. Несмотря на то, что затраты на сохранение всей страницы больше, чем затраты на запись небольшого измененного кусочка, система будет работать лучше.

Поэтому, чтобы узнать, что память swap действительно используется, мы должны из значения SwapUsed вычесть значение SwapCached, вы можете найти эту информацию в /proc/meminfo.

Подкачка памяти

Когда приложению нужна память, а вся оперативная память полностью занята, то в распоряжении ядра есть два способа освободить память: оно может либо уменьшить размер дискового кэша в оперативной памяти, убирая устаревшие данные, либо оно может сбросить на диск в swap раздел несколько достаточно редко используемых порций (страниц) программы. Трудно предсказать, какой из способов будет более эффективным. Ядро, исходя из недавней истории действий в системе, делает попытку приблизительно отгадать на данный момент эффективность каждого из этих двух методов.

До ядер версии 2.6 у пользователя не было возможности влиять на эти оценки, так что могла возникнуть ситуации, когда ядро часто делало неправильный выбор, что приводило к пробуксовыванию и низкой производительности. В версии 2.6 ситуация с подкачкой памяти была изменена.

Подкачке памяти назначается значение от 0 до 100, которое изменяет баланс между подкачкой памяти приложений и освобождением кэш памяти. При значении 100 ядро всегда предпочтет найти неактивные страницы и сбросить их на диск в раздел swap; в других случаях этот сброс будет осуществляться в зависимости от того, сколько памяти занимает приложение и насколько трудно выпонять кэширование при поиске и удалении неактивных элементов.

Читать еще:  Ошибка конфиденциальности в гугл хром

По умолчанию для этого устанавливается значение 60. Значение 0 дает нечто близкое к старому поведению, когда приложения, которым нужна память, заставляли немного уменьшить размер кэша оперативной памяти. Для ноутбуков, для которых предпочтительно иметь диски с меньшей скоростью вращения, рекомендуется использовать значение 20 или меньше.

Заключение

В этой статье я поместил информацию, которая была мне полезной в моей работе в качестве системного администратора, и я надеюсь, что она может оказаться полезной и для вас.

Тема 9: Управление памятью в linux

Дата добавления: 2013-12-23 ; просмотров: 3022 ; Нарушение авторских прав

1*. Структура памяти в linux

У каждого процесса в системе linux есть адресное пространство, разделенное на 3 логических сегмента

Содержит машинные команды, образующие исполняемый код программы. Он создается компилятором и ассемблером при трансляции программы в машинный код (только для чтения).

Содержит переменные, строки, массивы и другие данные программы. Он состоит из 2-х частей: инициализированные данные и неинициализированные данные. Инициализированная часть сегмента данных содержит переменные и константы компилятора, значения которых должны быть заданы при запуске. Все переменные в неинициализированной части должны быть сброшены в 0.

3. stack segment

На большинстве компьютеров он начинается около старших адресов виртуального адресного пространства и растет вниз к 0. Если указатель стека оказывается ниже нижней границы стека, то происходит аппаратное прерывание, при котором операционная система понижает границу сегмента стека на одну страницу. Когда программа запускается, ее стек не пуст, он содержит все переменные окружения, а также командную строку, введенную оболочке для вызова этой программы. Рассмотрим случай, когда два пользователя запускают одну и ту же программу (или один пользователь два раза одну и ту же программу). Здесь возможно 2 подхода:

1. Хранить в оперативной памяти две копии исходного текста программы

2. Оба процесса ссылаются на один и тот же участок памяти, где находится текст программы.

Во втором случае используется так называемый текстовый сегмент совместного использования. Сегменты данных и стека никогда не бывают общими. Процессы в linux могут обращаться к данным файлов при помощи отображения файлов на адресное пространство (memory mapped files). Эта функция позволяет отображать файл на часть адресного пространства процесса, чтобы можно было читать из файла и писать в файл так, как если бы это был массив байтов, хранящийся в памяти. Запись в этот файл одним из процессов мгновенно становится видимой всем остальным. Отображения на адресное пространство памяти временного файла представляет собой механизм реализации общей памяти для нескольких процессов. Сегмент данных может изменяться в отличие от сегмента текста. Linux разрешает сегменту данных расти при выделении памяти и уменьшаться при ее освобождению. С помощью системного вызова bkr процесс может установить размер своего сегмента данных. Этим системным вызовом активно пользуются malloc.

Управление физической памятью. Каждый процесс в системе linux на 32-разрядной машине получает 3 Гб виртуального адресного пространства для себя, а оставшийся 1 Гб памяти резервируется для его страничных таблиц и других данных ядра. 1 Гб ядра не виден в пользовательском режиме, но становится доступным в режиме ядра. Память ядра обычно находится в нижних физических адресах, но отображается в верхний гигабайт виртуального адресного пространства процесса. Адресное пространство создается с помощью вызова fork и перезаписывается при помощи системного вызова exec. Чтобы несоклько процессов могли совместно использовать физическую память linux отслеживает использование физической памяти, выделяет при необходимости дополнительную память пользовательским процессам и компонентам ядра, динамически отображает области физической памяти на адресное пространство различных процессов. В linux различают 3 зоны памяти:

1. ZONE_DMA – это страницы, которые можно использовать для операций DMA

2. ZONE_NORMAL – это нормальные отображаемые страницы

3.ZONE_HIGHMEM – Страницы с адресами в верхней области памяти, которые не имеют постоянного отображения. Точные границы и компоновка этих зон памяти зависит от архитектуры, например на платформах x86 некоторые устройства могут выполнять DMA операции только в 1-х 16 мегабайтах, следовательно зона DMA находится в диапазоне от 0 до 16 мегабайт. Ядро поддерживает структуру ZONE для каждой из этих 3-х зон и может выполнять выделение памяти для этих 3-х зон поотдельности. Основная память linux состоит из 3-х частей: 1-е две части – ядро и карта памяти (не вытесняются), остальная память разделена на страничные блоки, каждый из которых может содержать страницу текста, данных, стека, страницу с таблицей страниц или списки свободных страниц. Ядро поддерживает карту памяти, которая содержит всю информацию об использовании физической памяти системы.

Карта памяти организована следующим образом:

1. page desctiptor –описывает каждый физический страничный блок системы. Каждый дескриптор содержит указатель на адресное пространство, которому принадлежит страница, пару указателей, которые позволяют ему сформировать дважды связный список с другими дескрипторами (если страницы свободны) и прочие поля, размер дескриптора страницы равен 32 байтам.

2. zone descriptor – содержит информацию об использовании памяти в зоне, такую как количество активных и неактивных страниц нижний и верхний пределы для алгоритмов замещения страниц и др. Кроме того, дескриптор зоны содержит массив свободных областей. Первый элемент этого массива указывает на 1-й дескриптор страницы 1-го блока и свободных страниц. Наличие данной структуры обусловлено возможностью системы linux переноса на архитектуру NUMA. Каждый дескриптор узла содержит информацию об использовании памяти и зонах для данного конкретного узла.

Физическая память используется для различных целей, части которой могут выгружаться или не выгружаться на жесткий диск. Ядро системы, как и ни одна из его частей не выгружается на диск, остальная часть памяти доступна для страниц пользователей.

Кроме того операционная система linux поддерживает динамически загружаемые модули, в основном драйверы устройств. Они могут быть большего размера и каждому из них должен быть выделен непрерывный участок ядра памяти.

Виртуальный адрес страницы в linux состоит из 5 частей:

1. Глобальный каталог

2. Верхний каталог

3. Средний каталог

В системе linux используется 4-х уровневая схема таблиц страниц. Поля каталогов используются как индекс в соответствующем каталоге страниц. Глобальный каталог указывает на верхний каталог, верхний каталог указывает на средний и средний указывает на конкретную страницу, которую необходимо использовать в данный момент времени.

Виртуальная память в Linux

ТЕМА 7. РАБОТА С ОПЕРАЦИОННЫМИ СИСТЕМАМИ. СОВРЕМЕННЫЕ ОПЕРАЦИОННЫЕ СИСТЕМЫ

Лекция 4. Обзор архитектуры и возможностей системы Linux.

1. Управление физической памятью в Linux.

2. Виртуальная память в Linux.

3. Исполнение и загрузка пользовательских программ в Linux.

4. Системы файлов Linux.

5. Ввод и вывод в Linux.

6. Взаимодействие процессов в Linux.

7. Структура сети в Linux.

8. Безопасность в Linux.

9. Развитие и использование Linux

Управление физической памятью в Linux

Система распределения физической памяти в Linux занимается размещением и освобождением страниц, групп страниц и небольших блоков памяти. Она имеет дополнительные механизмы для виртуальной памяти, отображаемой в адресное пространство исполняемых процессов.

Распределитель страниц размещает и освобождает физические страницы; он может также по запросу размещать группы смежных страниц.

Распределитель страниц Linux использует алгоритм buddy-heap (партнерской кучи)для слежения за доступными физическими страницами, принципы которого в следующем:

· Каждая область памяти, подлежащая распределению, образует пару с ее смежным «партнером».

· Когда обе области-партнера освобождаются, они сливаются и образуют смежную область вдвое большего размера.

· Если не существует малой области памяти, чтобы удовлетворить небольшой запрос на память, то область памяти большего размера расщепляется на две области-партнера для удовлетворения данного запроса.

Распределение памяти для ядра Linux возможно как статическое (драйвер резервирует статическую область памяти во время загрузки системы) или динамическое (с помощью распределителя страниц).

Расщепление памяти в куче изображено на рис.1.

Рис. 1.Расщепление памяти в куче в системе Linux.

Виртуальная память в Linux

Система виртуальной памяти в Linux поддерживает адресное пространство, видимое каждому процессу: она создает страницы виртуальной памяти по требованию и управляет загрузкой этих страниц с диска или откачкой их обратно на диск, если требуется.

Менеджер виртуальной памяти поддерживает две точки зрения на адресное пространство каждого процесса:

· Логическую– поддержка команд управления адресным пространством. Адресное пространство рассматривается как совокупность непересекающихся смежных областей.

· Физическую– с помощью таблицы страниц для каждого процесса.

Для управления виртуальной памятью используются:

· Файл откачки (backing store),описывающий, откуда берутся страницы для заданного региона; регионы обычно поддерживаются либо файлом, либо не поддерживаются вообще (память, обнуляемая по требованию)

· Реакция региона на запись (совместное использование страниц или копирование при записи — COW).

Ядро создает новое виртуальное адресное пространство:

· Когда процесс запускает новую программу системным вызовом exec;

· При создании нового процесса системным вызовом fork.

При исполнении новой программы процессу предоставляется новое, пустое адресное пространство; процедуры загрузки программ наполняют это адресное пространство регионами виртуальной памяти.

Создание нового процесса с помощью fork включает создание полной копии адресного пространства существующего процесса.

Ядро копирует дескрипторы доступа к виртуальной памяти родительского процесса, затем создает новый набор таблиц страниц для дочернего процесса.

Таблицы страниц процесса-родителя копируются непосредственно в таблицы страниц дочернего, причем счетчик ссылок на каждую страницу увеличивается.

После исполнения fork родительский и дочерний процесс используют одни и те же физические страницы в своих виртуальных адресных пространствах.

Система управления страницами откачивает страницы физической памяти на диск, если они требуются для какой-либо другой цели.

Система управления страницами делится на две части:

· Алгоритм откачки, который определяет, какие страницы и когда откачать на диск;

· Механизм подкачки фактически выполняет передачу и подкачивает данные обратно в физическую память, если требуется.

Ядро Linux резервирует постоянный, зависящий от архитектуры регион виртуального адресного пространства каждого процесса для его собственного внутреннего использования.

Эта область виртуальной памяти ядра содержит два региона:

· Статическую область, содержащую ссылки из таблицы страниц на каждую доступную физическую страницу памяти в системе, так что используется простая трансляция физического адреса в виртуальный при исполнении кода ядра.

· Остаток зарезервированной части не используется ни для какой другой цели; его элементы таблицы страниц могут быть модифицированы и указывать на любые страницы в памяти.

Ссылка на основную публикацию
Adblock
detector