Я отвечаю на тег Linux . Мой ответ специфичен только для Linux .
Да, огромные страницы более подвержены фрагментации. Существует два вида памяти: тот, который получает ваш процесс (виртуальный), и тот, которым ядро управляет (реальный). Чем больше любая страница, тем сложнее будет сгруппировать (и сохранить ее) своих соседей, особенно когда ваш сервис работает в системе, которая также должна поддерживать другие, которые по умолчанию выделяют и записывают в память больше памяти, чем они. на самом деле в конечном итоге с помощью.
Отображение ядром (реальных) предоставленных адресов является закрытым. Существует очень веская причина, по которой пользовательское пространство видит их так, как их представляет ядро, потому что ядро должно иметь возможность выполнять перегрузку, не путая пользовательское пространство. Ваш процесс получает хорошее непрерывное адресное пространство «Disneyfied» для работы, не обращая внимания на то, что ядро фактически делает с этой памятью за кулисами.
Причина, по которой вы видите снижение производительности на долго работающих серверах, наиболее вероятна из-за того, что выделенные блоки, которые не были явно заблокированы (например, mlock()
/ mlockall()
или posix_madvise()
) и не модифицированы в течение некоторого времени, были выгружены , что означает, что ваша служба переходит на диск, когда она должна прочитать их. Изменение этого поведения делает ваш процесс плохим соседом , поэтому многие люди размещают свои RDBMS на совершенно другом сервере, чем web / php / python / ruby / что угодно. Разумно, единственный способ исправить это - снизить конкуренцию за смежные блоки.
Фрагментация действительно заметна (в большинстве случаев) только тогда, когда страница A находится в памяти, а страница B перемещена в область подкачки. Естественно, перезапуск вашего сервиса, похоже, «излечит» это, но только потому, что ядро еще не имело возможности вывести из процесса (в настоящее время) вновь выделенные блоки в пределах его коэффициента перегрузок.
Фактически, перезапуск (скажем, «apache») при высокой нагрузке, скорее всего, отправит блоки, принадлежащие другим сервисам, прямо на диск. Так что да, «apache» улучшится на короткое время, но «mysql» может пострадать… по крайней мере, пока ядро не заставит их страдать одинаково, когда просто не хватает достаточной физической памяти.
Добавьте больше памяти или разделите требовательных malloc()
потребителей :) Это не просто фрагментация, на которую вам нужно смотреть.
Попробуйте vmstat
получить обзор того, что на самом деле хранится где.