Очистка освобождаемых областей оперативной памяти linux

Очистка освобождаемых областей оперативной памяти в процессе освобождения страниц в GNU/Linux

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

Linux, очистка памяти, free_pages, brk, free_pages_prepare

Cleaning of freed memory areas in the process of freeing pages in GNU / Linux.

The article describes the topicality of cleaning freed memory areas. The approach based on cleaning of freed memory areas at the moment of freeing pages of random access memory is offered.

Linux, memory cleaning, free_pages, brk, free_pages_prepare

В настоящее время ОС на базе ядра Linux все больше используются, в том числе и в государственных организациях, а, следовательно, и появляется потребность в сертифицированных СЗИ НСД для Linux. Согласно руководящим документам РФ для успешного прохождения процедуры сертификации на определенные классы (5-й класс СВТ и выше) средствам защиты от НСД необходим механизм очистки освобождаемых областей оперативной памяти.

Рисунок 1: Освобождение областей оперативной памяти

На рисунке 1 изображена схема освобождения областей оперативной памяти — приложение может очищать память либо используя стандартную библиотеку glibc, либо напрямую вызывая системные вызовы. Поскольку приложение может и не использовать стандартную библиотеку, подсистему очистки освобождаемой оперативной памяти можно реализовывать либо на уровне интерфейса системных вызовов, либо на уровне освобождения страниц.

В статье [1] был рассмотрен способ реализации очистки освобождаемой оперативной памяти в ОС Linux на уровне интерфейса системных вызовов. Данный подход основывался на перехвате системных вызовов: brk, munmap, mremap, exit, exit_group, close и имел определенные недостатки: невозможность очищать разделяемые области памяти, области памяти, принадлежащие ядру ОС и приводил к заметному снижению производительности.

Второй подход — реализация подсистемы очистки освобождаемой оперативной памяти на уровне освобождения страниц — лишен этих недостатков. Данный подход заключается в том, чтобы модифицировать поведение функции/функций, освобождающих страницы оперативной памяти.

Есть два пути изменить поведение ядра ОС — изменить исходный код и пересобрать ядро Linux, либо загрузить модуль ядра, перехватывающий функции, поведение которых нужно поменять. Примером следования первому пути является патч к ядру Linux — PaX. В рамках своих функций он может производить очистку освобождаемых страниц оперативной памяти. Однако использование патча к ядру создает трудности в установке и эксплуатации комплекса СЗИ НСД. Для установки комплекса на дистрибутив Linux необходимо найти исходники ядра, затем приложить патч и пересобрать. При обновлении ядра Linux необходимо будет повторить процедуру. Кроме того, затрудняется сертификация — необходимо сертифицировать все ядро, так как оно в этом случае является частью комплекса. Среди плюсов данного пути можно выделить отсутствие любых ограничений на изменение поведения ядра. Из-за всего вышеперечисленного для создания подсистемы комплекса СЗИ НСД куда лучше подходит второй путь, который и рассматривается в данной статье.

В данной статье рассматривается реализация только для конкретной версии ядра (2.6.35), однако она с небольшими исправлениями может быть применима для более современных версий ядра. В ядре Linux рассматриваемой версии функцией, которая вызывается для освобождения страниц, является free_pages. Однако эта функция является всего лишь интерфейсом к функциям, которые производят реальное освобождение страниц ядром ОС и процессором (если архитектура процессора это допускает). В итоге вызова этой функции всегда вызывается функция free_pages_prepare. Данная функция принимает среди параметров дескриптор страницы, производит определенные проверки и вызывает функцию arch_free_pages, которая должна производить окончательное освобождение страниц. Но на большинстве архитектур, в том числе и на x86, данная функция является пустой и не производит никаких действий и ее нельзя перехватить из-за отсутствия ее адреса в таблице символов ядра. То есть, в зависимости от архитектуры, необходимо либо перехватывать arch_free_pages, либо free_pages_prepare.

Читайте также:  Как правильно устанавливать linux mint

Перехват проще всего производить путем записи команды ud2 в начало кода функции, предварительно сохранив поврежденный участок начала функции. Данная команда вызывает обрабатываемое исключение, и в качестве обработчика этого исключения можно назначить функцию-перехватчик, и в функции перехватчике возвращать управление на сохраненный пролог, а затем в прологе — на оставшуюся часть функции. Для того, чтобы определить длину перезаписанной команды, необходим код, вычисляющий длины команд (дизасемблер длин), что делает перехват функции ядра архитектурно-зависимым. Подробно этот процесс описан с статье [5].

В зависимости от архитектуры процессора, как было сказано выше, перехватывать нужно либо функцию arch_free_pages, либо free_pages_prepare. В последнем случае необходимо выполнить все проверки, которые проводит функция free_pages_prepare до вызова arch_free_pages, и в случае их успешного прохождения очищать группу освобождаемых страниц оперативной памяти. Одним из параметров этих функций является параметр order — степень, в которую необходимо возвести двойку, чтобы получить число страниц. Другим параметром является указатель на массив дескрипторов страниц, используя которые, можно очистить освобождаемые страницы.

Чтобы очистить страницу оперативной памяти, зная ее дескриптор, необходимо сначала отобразить ее в виртуальную память ядра. Это можно сделать при помощи двух функций — kmap и kmap_atomic. Первая функция использует внутри себя различные блокировки, и не может использоваться в атомарном контексте, в то время, как функция free_pages_prepare может вызываться в таком контексте и использование функции kmap может привести к панике ядра (kernel panic). Поэтому в данном случае можно использовать только функции kmap_atomic/kunmap_atomic. Кроме того, при очистке страницы необходимо отключить на время прерывания при помощи функции local_irq_save, соответственно после очистки включить функцией local_irq_restore.

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

Для создания средства или подсистемы очистки освобождаемых областей оперативной памяти, которое не замедляет работу ОС и очищает все освобождаемые участки оперативной памяти, лучше подходит способ, основанный на перехвате функции ядра Linux, освобождающей страницы оперативной памяти. Тем не менее, он не очищает сегмент кучи при уменьшении его размера посредством системного вызова brk, таким образом, в данном подходе желательно перехватывать системный вызов brk (то есть использовать оба подхода). Данный вопрос был подробно разобран в статье [1].

  1. Прокопов В. С., Каннер А. М. Особенности реализации механизма очистки освобождаемых областей оперативной памяти в GNU/Linux //Комплексная защита информации. Электроника инфо. Материалы XVIII Международной конференции 21–24 мая 2013 года, Брест (Республика Беларусь). 2013. С. 120–123.
  2. Бовет Д., Чезати М. Ядро Linux. 3 изд. СПб: БХВ-Петербург, 2007. 1104 с.
  3. Руководящий документ «Средства вычислительной техники. Защита от несанкционированного доступа к информации. Показатели защищенности от несанкционированного доступа к информации»//Гостехкомиссия России, 1992.
  4. Руководящий документ «Автоматизированные системы. Защита от несанкционированного доступа к информации. Классификацияавтоматизированных систем и требования по защите информации»//Гостехкомиссия России, 1992.
  5. Перехват функций ядра Linux с использованием исключений (kprobes своими руками) //http://habrahabr.ru/post/206778/
Читайте также:  Canon support printer drivers windows

Автор: Прокопов В. С.

Дата публикации: 01.01.2014

Библиографическая ссылка: Прокопов В. С. Очистка освобождаемых областей оперативной памяти в процессе освобождения страниц в GNU/Linux // Вопросы защиты информации: Научно-практический журнал. М.: ФГУП «ВИМИ», 2014. Вып. 4 (107). С. 24–26.

Источник

Как освободить память Linux

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

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

Как освободить кэш память в Linux

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

Затем выполните одну из команд. Очистка кэша PageCache:

sync; echo 1 > /proc/sys/vm/drop_caches

Очистка inode и dentrie:

sync; echo 2 > /proc/sys/vm/drop_caches

Очистка inode и dentrie и PageCache:

sync; echo 3 > /proc/sys/vm/drop_caches

А теперь давайте рассмотрим что происходит при выполнении этих команд.

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

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

Символ разделения ; дает знать оболочке, что перед тем как выполнить другую команду, нужно дождаться завершения работы первой. Последняя команда echo 1 > /proc/sys/vm/drop_caches записывает значение 1 в файл /proc/sys/vm/drop_caches. Это дает сигнал ядру, что нужно очистить выбранный нами вид кэша.

Виды кэша в Linux

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

PageCache или страничный кэш — это место, куда ядро складывает все данные, которые вы записывали или читали из диска. Это очень сильно ускоряет работу системы, так как если программе во второй раз понадобятся те же данные, они просто будут взяты из оперативной памяти. Но по этой причине этот кэш занимает больше всего места.

Посмотреть размер страничного кэша можно с помощью утилиты free. Здесь он показан в последней колонке — cached:

Такой кэш чистить эффективнее и безопаснее всего.

Кэш inode и dentrie тоже относится к файловой системе. Только в него записываются не сами данные, а структура файловой системы, расположение файлов и папок. При запросе расположения файла или содержимого папки ядро формирует специальные структуры, в которых есть вся эта информация. При следующем запросе структуры будут уже сохранены в памяти. Для каждой файловой системы существует свой кэш inode и общий кэш dentrie.

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

cat /proc/slabinfo | egrep dentry\|inode

Очищать его чтобы освободить память linux не рекомендуется, так как памяти потребляется немного, а на новое сканирование файловой системы идет относительно много времени.

Читайте также:  Pfx to cer windows

Нужно ли очищать кэш вообще?

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

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

Автоматическая очистка кэша

Давайте рассмотрим как автоматически очистить кэш памяти ежедневно в два часа ночи с помощью планировщика заданий cron.

Сначала создадим bash скрипт со следующим содержимым:

sudo vi /usr/local/bin/clearcache.sh

!/bin/bash
sync ; echo 1 > /proc/sys/vm/drop_caches

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

Дальше сделайте скрипт исполняемым:

sudo chmod 755 /usr/local/bin/clearcache.sh

Осталось добавить задание в планировщик cron. Для этого выполните команду:

И в открывшемся редакторе добавьте строчку:

0 2 * * * /usr/local/bin/clearcache.sh

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

Настройка размера кэша памяти

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

За это отвечает файл /proc/sys/vm/vfs_cache_pressure. Он содержит относительный показатель, насколько агрессивно нужно удалять страницы из кэша. По умолчанию установлен параметр 100. Если его уменьшить ядро будет реже удалять страницы и это приведет к очень быстрому увеличению кэша. При нуле страницы вообще не будут удаляться. Если значение больше 100, размер кэша будет увеличиваться медленнее и неиспользуемые страницы будут сразу удаляться.

Например, сделаем минимальный размер кэша:

echo 1000 > /proc/sys/vm/vfs_cache_pressure

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

Как очистить память подкачки

Пространство подкачки очистить очень просто. Для этого выполните:

swapoff -a && swapon -a

Имейте в виду, что при очистке swap, все данные будут перенесены обратно в оперативную память.

Как освободить память занимаемую процессами

Если в вашей системе нет памяти и кэш здесь ни при чём, следует завершить несколько процессов, потребляющих больше всего памяти. Для этого сначала надо вычислить такие процессы. Чтобы это сделать можно воспользоваться утилитой ps:

ps -e -o pid,user,%mem,command —sort %mem

Как видите, больше всего здесь памяти занимает chromium. Теперь вам надо его завершить. Идентификатор процесса, по которому его можно завершить отображается в первой колонке. Поэтому:

Более подробно о том как завершить процесс читайте в этой статье. Таким образом, вы можете освободить память от процессов, которые занимают больше всего памяти, а потом уже настроить zram или swap для того, чтобы память не переполнялась.

Выводы

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

Источник

Оцените статью