- Разбирался с page-cache в Linux
- 2014/10/09
- Page cache linux ��� ���
- How to clear the buffer/pagecache (disk cache) under Linux
- What is Memory Cache
- What is the purpose of /proc/sys/vm/drop_caches
- How to clear the Memory Cache using /proc/sys/vm/drop_caches
- How to clear the Memory Cache using sysctl
- Как освободить память Linux
- Как освободить кэш память в Linux
- Виды кэша в Linux
- Нужно ли очищать кэш вообще?
- Автоматическая очистка кэша
- Настройка размера кэша памяти
- Как очистить память подкачки
- Как освободить память занимаемую процессами
- Выводы
Разбирался с page-cache в Linux
2014/10/09
Читая книгу “Разработка ядра Linux” за авторством Роберта Лава, я решил поглубже разобраться в том, как работает кэш в Linux, и набрел на вот эту статью на Хабре от Яндекса.
Сама статья весьма познавательна, особенно видео — рекомендую. Так вот, в этом видео Роман Гущин, с помощью простой утилиты, наглядно показывающей размер кэша, показывал как работает файловый кэш.
Конечно, мне захотелось в образовательных целях написать такую утилиту для себя, чтобы можно было поиграться с кэшем и видеть изменения.
Выбрал я для реализации свой любимый Python в связке с Qt(PySide).
Актуальная версия визуализатора лежит в моем репозитории.
Теперь можно самому повторить эксперимент из видео на новых ядрах, и посмотреть, что же изменилось.
Предварительно надо создать пару больших файлов, для 8Gb оперативки нам нужны 1Gb и 8Gb файлы. Создать их можно из /dev/urandom примерно так:
А еще надо собрать vmtouch:
Ну а теперь повторяем эксперимент из видео. Я использовал ядро Linux 3.13.
Для начала, сбросим кэши:
У нас есть два больших файлика — large и large2:
Прочитаем large, чтобы он попал в inactive cache:
Прочитаем его еще раз, чтобы он попал в active cache:
Теперь можно натравить на него vmtouch:
Выдавим его из кэша:
Снова прочитаем large, чтобы он попал в inactive cache:
Теперь прочитаем large2
и видим, что он вытесняет large из inactive cache.
А теперь сбросим снова кэши, и запихнем large в active cache:
И попробуем прочитать large2:
Теперь мы можем видеть, что large2 не может вытеснить large из active cache, о чем и говорилось в видео.
А еще видно, как колеблется количество свободной памяти, из-за периодического характера работы kswapd.
Если посмотреть с помощью vmtouch, какая часть large2 попала в inactive cache, то мы увидим, что он при чтении вытеснял сам себя.
Теперь можно удалить large, и увидеть, как освободился active cache, а потом удалить large2 и увидеть, как освободился inactive cache.
Вот такой вот опыт позволяет увидеть некоторые проблемы в работе с кэшами в актуальных ядрах Linux. Будет интересно повторить эксперимент на свежих ядрах после улучшений в области Memory Management.
© Alexander Bulimov 2013 – 2021 | Github
Источник
Page cache linux ��� ���
В этой главе будет описан Linux 2.4 pagecache. Pagecache — это кэш страниц физической памяти. В мире UNIX концепция кэша страниц приобрела известность с появлением SVR4 UNIX, где она заменила буферный кэш, использовавшийся в операциях вода/вывода.
В SVR4 кэш страниц предназначен исключительно для хранения данных файловых систем и потому использует в качестве хеш-параметров структуру struct vnode и смещение в файле, в Linux кэш страниц разрабатывлся как более универсальный механизм, использущий struct address_space (описывается ниже) в качестве первого параметра. Поскольку кэш страниц в Linux тесно связан с понятием адресных пространств, для понимания принципов работы кэша страниц необходимы хотя бы основные знания об adress_spaces. Address_space — это некоторое программное обеспечение MMU (Memory Management Unit), с помощью которого все страницы одного объекта (например inode) отображаются на что-то другое (обычно на физические блоки диска). Структура struct address_space определена в include/linux/fs.h как:
Для понимания принципов работы address_spaces, нам достаточно остановиться на некоторых полях структуры, указанной выше: clean_pages , dirty_pages и locked_pages являются двусвязными списками всех «чистых», «грязных» (измененных) и заблокированных страниц, которые принадлежат данному адресному пространству, nrpages — общее число страниц в данном адресном пространстве. a_ops задает методы управления этим объектом и host — указатель на inode, которому принадлежит данное адресное пространство — может быть NULL, например в случае, когда адресное пространство принадлежит программе подкачки ( mm/swap_state.c, ).
Назначение clean_pages , dirty_pages , locked_pages и nrpages достаточно прозрачно, поэтому более подробно остановимся на структуре address_space_operations , определенной в том же файле:
Для понимания основ адресных пространств (и кэша страниц) следует рассмотреть -> writepage и -> readpage , а так же -> prepare_write и -> commit_write .
Из названий методов уже можно предположить действия, которые они выполняют, однако они требуют некоторого уточнения. Их использование в ходе операций ввода/вывода для более общих случаев дает хороший способ для их понимания. В отличие от большинства других UNIX-подобных операционных систем, Linux имеет набор универсальных файловых операций (подмножество операций SYSV над vnode) для передачи данных ввода/вывода через кэш страниц. Это означает, что при работе с данными отсутствует непосредственное обращение к файловой системе (read/write/mmap), данные будут читаться/записываться из/в кэша страниц (pagecache), по мере возможности. Pagecache будет обращаться к файловой системе либо когда запрошенной страницы нет в памяти, либо когда необходимо записать данные на диск в случае нехватки памяти.
При выполнении операции чтения, универсальный метод сначала пытается отыскать страницу по заданным inode/index.
Затем проверяется — существует ли заданная страница.
hash = page_hash(inode->i_mapping, index); page = __find_page_nolock(inode->i_mapping, index, *hash);
Если таковая отсутствует, то в памяти размещается новая страница и добавляется в кэш.
page = page_cache_alloc();
__add_to_page_cache(page, mapping, index, hash);
После этого страница заполняется данными с помощью вызова метода -> readpage .
И в заключение данные копируются в пользовательское пространство.
Для записи данных в файловую систему существуют два способа: один — для записи отображения (mmap) и другой — системный вызов write(2). Случай mmap наиболее простой, поэтому рассмотрим его первым. Когда пользовательское приложение вносит изменения в отображение, подсистема VM (Virtual Memory) помечает страницу.
Поток ядра bdflush попытается освободить страницу, в фоне или в случае нехватки памяти, вызовом метода -> writepage для страниц, которые явно помечены как «грязные». Метод -> writepage выполняет запись содержимого страницы на диск и освобождает ее.
Второй способ записи намного более сложный. Для каждой страницы выполняется следующая последовательность действий (полный исходный код смотрите в mm/filemap.c:generic_file_write() ).
page = __grab_cache_page(mapping, index, &cached_page);
mapping->a_ops->prepare_write(file, page, offset, offset+bytes);
copy_from_user(kaddr+offset, buf, bytes);
mapping->a_ops->commit_write(file, page, offset, offset+bytes);
Сначала делается попытка отыскать страницу либо разместить новую, затем вызывается метод -> prepare_write , пользовательский буфер копируется в пространство ядра и в заключение вызывается метод -> commit_write . Как вы уже вероятно заметили -> prepare_write и -> commit_write существенно отличаются от -> readpage и -> writepage , потому что они вызываются не только во время физического ввода/вывода, но и всякий раз, когда пользователь модифицирует содержимое файла. Имеется два (или более?) способа обработки этой ситуации, первый — использование буферного кэша Linux, чтобы задержать физический ввод/вывод, устанавливая указатель page->buffers на buffer_heads, который будет использоваться в запросе try_to_free_buffers ( fs/buffers.c ) при нехватке памяти и широко использующийся в текущей версии ядра. Другой способ — просто пометить страницу как «грязная» и понадеяться на -> writepage , который выполнит все необходимые действия. В случае размера страниц в файловой системе меньшего чем PAGE_SIZE этот метод не работает.
Источник
How to clear the buffer/pagecache (disk cache) under Linux
Are you facing a performance issue and you suspect it might be related to cache usage? High cache usage should not normally cause performance issues, but it might be the root cause in some rare cases.
What is Memory Cache
In order to speed operations and reduce disk I/O, the kernel usually does as much caching as it has memory By design, pages containing cached data can be repurposed on-demand for other uses (e.g., apps) Repurposing memory for use in this way is no slower than claiming pristine untouched pages.
What is the purpose of /proc/sys/vm/drop_caches
Writing to /proc/sys/vm/drop_caches allows one to request the kernel immediately drop as much clean cached data as possible. This will usually result in some memory becoming more obviously available; however, under normal circumstances, this should not be necessary.
How to clear the Memory Cache using /proc/sys/vm/drop_caches
Writing the appropriate value to the file /proc/sys/vm/drop_caches causes the kernel to drop clean caches, dentries and inodes from memory, causing that memory to become free.
1. In order to clear PageCache only run:
2. In order to clear dentries (Also called as Directory Cache) and inodes run:
3. In order to clear PageCache, dentries and inodes run:
Running sync writes out dirty pages to disks. Normally dirty pages are the memory in use, so they are not available for freeing. So, running sync can help the ensuing drop operations to free more memory.
Page cache is memory held after reading files. Linux kernel prefers to keep unused page cache assuming files being read once will most likely to be read again in the near future, hence avoiding the performance impact on disk IO.
dentry and inode_cache are memory held after reading directory/file attributes, such as open() and stat(). dentry is common across all file systems, but inode_cache is on a per-file-system basis. Linux kernel prefers to keep this information assuming it will be needed again in the near future, hence avoiding disk IO.
How to clear the Memory Cache using sysctl
You can also Trigger cache-dropping by using sysctl -w vm.drop_caches=[number] command.
1. To free pagecache, dentries and inodes, use the below command.
2. To free dentries and inodes only, use the below command.
3. To free the pagecache only, use the below command.
Источник
Как освободить память 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 не рекомендуется, так как памяти потребляется немного, а на новое сканирование файловой системы идет относительно много времени.
Нужно ли очищать кэш вообще?
Во-первых, если занято очень много памяти, вы можете очистить страничный кэш, особенно если это он занимает много памяти. Во-вторых, очистить кэш памяти 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 и освободить память. Не забудьте, что все команды, приведенные в этой статье нужно выполнять от имени суперпользователя, иначе ничего работать не будет. Если остались вопросы, спрашивайте в комментариях!
Источник