Фрагментация памяти Linux

Если Вы уже не попробовали:

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

20
задан 16 April 2010 в 12:03
4 ответа

Я отвечаю на тег . Мой ответ характерен только для Linux.

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

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

Причина Вы видите ухудшенную производительность на длительных серверах, наиболее вероятна, потому что выделенные блоки, которые не были явно заблокированы (например. mlock()/mlockall() или posix_madvise()) и не измененный в некоторое время были разбиты на страницы, что значит Ваши сервисные блоки для диска, когда он должен считать их. Изменение этого поведения делает Ваш процесс плохим соседом, который является, почему многие люди помещают свой RDBMS на совершенно другой сервер, чем web/php/python/ruby/whatever. Единственный способ зафиксировать это, нормально, состоит в том, чтобы уменьшить борьбу за непрерывные блоки.

Фрагментация только действительно примечательна (в большинстве случаев), когда страница A находится в памяти, и страница B переместилась в подкачку. Естественно, перезапуск Вашего сервиса, казалось бы, 'исправил' бы это, но только потому, что ядро еще не имело возможности разбить на страницы процесс (теперь) недавно выделенные блоки в рамках ограничений превышать возможности отношения.

На самом деле перезапуск (позволяет, говорит), 'апач' при высокой загрузке, вероятно, собирается отправить блоки, принадлежавшие другим сервисам прямо к диску. Таким образом да, 'апач' улучшился бы в течение короткого времени, но 'mysql' мог бы пострадать.. по крайней мере, пока ядро не заставляет их пострадать одинаково, когда существует просто отсутствие вполне достаточной физической памяти.

Добавьте больше памяти или разделите требование malloc() потребители :) Не просто фрагментация, на которую необходимо смотреть.

Попробовать vmstat получить обзор того, что на самом деле хранится где.

12
ответ дан 2 December 2019 в 20:12
  • 1
    Спасибо за ответ. Я использовал огромные страницы (размер = 2048 КБ каждый) для mysql - innodb пул буферов - чтобы видеть, как хорошо он тарифицирует (использующий sysbench). Первоначально, когда время работы процесса (и даже системное время работы) были низкими, это давало очень хорошие результаты. Однако его производительность начала ухудшаться по нескольким выполнениям. Относительно страницы Вы упомянули, я, конечно, заметил высокое действие VM, но я предположил, что это, возможно, было из-за сравнительного теста и сбрасывания журнала innodb (vm действие выше с огромными страницами, чем без). Я также установил vm.swappiness на 1. Я не мог заметить радикальное изменение. –  Raghu 16 April 2010 в 16:49

Используя огромные страницы не должен вызывать фрагментацию дополнительной памяти на Linux; поддержка Linux огромных страниц только для общей памяти (через shmget или mmap), и любые огромные используемые страницы должен конкретно требовать и предварительно выделить системный администратор. Однажды в памяти, они прикрепляются там и не выгружаются. Проблема загрузки огромных страниц перед лицом фрагментации памяти состоит точно в том, почему они остаются прикрепленными в памяти (при выделении 2 МБ огромная страница, ядро должно найти 512 непрерывных свободных страниц 4KB, которые даже не могут существовать).

Документация Linux на огромных страницах: http://lwn.net/Articles/375098/

Существует одно обстоятельство, где фрагментация памяти могла заставить огромное выделение страницы быть медленным (но не, где огромные страницы вызывают фрагментацию памяти), и это - то, если Ваша система настроена для роста пула огромных страниц, если требуется приложением. Если/proc/sys/vm/nr_overcommit_hugepages больше, чем/proc/sys/vm/nr_hugepages, это могло бы произойти.

4
ответ дан 2 December 2019 в 20:12

Ядро

Для получения текущего индекса фрагментации используйте:

sudo cat /sys/kernel/debug/extfrag/extfrag_index

Для дефрагментации памяти ядра попробуйте выполнить:

sysctl vm.compact_memory=1  

Также попробуйте отключить прозрачные огромные страницы (также известные как THP) и / или отключить подкачку (или уменьшить swappiness ).

Пользовательское пространство

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

Вы можете переключиться на пользовательский malloc, перекомпилировав с ним свою программу или просто запустив ее с LD_PRELOAD : LD_PRELOAD = $ {JEMALLOC_PATH} /lib/libjemalloc.so.1 app (остерегайтесь взаимодействий между THP и распределителями памяти )

Хотя, это немного не связано с фрагментацией памяти (но связано с уплотнением / переносом памяти), вы, вероятно, захотите запустить несколько экземпляров вашей службы, один для каждый узел NUMA и свяжите их, используя numactl .

5
ответ дан 2 December 2019 в 20:12

Есть очень полезный / proc / buddyinfo . Это более полезно с красивым выходным форматом, как этот сценарий Python может сделать:

https://gist.github.com/labeneator/9574294

Для огромных страниц вам нужны бесплатные фрагменты размером 2097152 (2 МБ) или больше. Для прозрачных огромных страниц он автоматически сжимается, когда ядро ​​запрашивает некоторые, но если вы хотите увидеть, сколько вы можете получить, то выполните от имени root:

echo 1 | sudo tee /proc/sys/vm/compact_memory

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

У меня есть решение, которое мне подходит. Я использую его на нескольких серверах и на своем ноутбуке. Он отлично работает для виртуальных машин.

Добавьте параметр kernelcore = 4G в командную строку ядра Linux. На моем сервере я использую 8G. Будьте осторожны с числом, потому что это помешает вашему ядру выделить что-либо за пределами этой памяти. Серверы, которым требуется много буферов сокетов или которые записывают потоки с диска на сотни дисков, не будут иметь таких ограничений. Любое выделение памяти, которое должно быть «закреплено» для slab или DMA, относится к этой категории.

Вся остальная ваша память становится «подвижной», что означает, что ее можно сжать в красивые куски для выделения огромных страниц. Теперь прозрачные огромные страницы действительно могут взлететь и работать так, как должны. Когда ядру требуется больше 2M страниц, оно может просто переназначить страницы 4K в другое место.

И я не совсем уверен, как это взаимодействует с прямым вводом-выводом с нулевым копированием. Память в «подвижной зоне» не должна быть закреплена, но прямой запрос ввода-вывода сделает именно это для DMA. Он может скопировать это. В любом случае он может закрепить его в подвижной зоне. В любом случае, вероятно, это не совсем то, что вам нужно.

0
ответ дан 2 December 2019 в 20:12

Теги

Похожие вопросы