Я відповідаю на тег Linux . Моя відповідь специфічна лише для Linux .
Так, величезні сторінки більш схильні до фрагментації. Є два види пам’яті, той, який отримує ваш процес (віртуальний) і той, яким керує ядро (реальний). Чим більша будь-яка сторінка, тим складніше буде згрупувати (і зберегти з нею) своїх сусідів, особливо коли ваша служба працює в системі, яка також повинна підтримувати інших, які за замовчуванням виділяють і записують у спосіб більше пам'яті, ніж вони фактично в кінцевому рахунку використовувати.
Зображення ядра (реальних) наданих адрес приватне. Є дуже вагома причина, чому користувацький простір бачить їх, як ядро представляє їх, тому що ядро повинно мати можливість перезавантажуватися, не плутаючи простір користувачів. Ваш процес отримує приємний, суміжний "розчленований" адресний простір, в якому потрібно працювати, не зважаючи на те, що ядро насправді робить із цією пам'яттю за кадром.
Причина, по якій ви бачите погіршену продуктивність на довго працюючих серверах, швидше за все, тому, що виділені блоки, які не були явно заблоковані (наприклад, mlock()
/ mlockall()
або posix_madvise()
) і не були змінені протягом певного часу, були завантажені на сторінку , а це означає, що ваші службові ковзання на диск, коли він повинен читати їх. Змінення такої поведінки робить ваш процес поганим сусідом , тому багато людей ставлять свої RDBMS на зовсім інший сервер, ніж web / php / python / ruby / будь-який інший. Єдиний спосіб виправити це, справедливо, - зменшити конкуренцію за сусідні блоки.
Фрагментація дійсно помітна (у більшості випадків) лише тоді, коли сторінка A знаходиться в пам'яті, а сторінка B перейшла на своп. Звичайно, перезапуск вашої служби, здавалося б, "вилікує" це, але тільки тому, що ядро ще не мало можливості викласти процес "(зараз) щойно виділених блоків у межах його коефіцієнта перевиконання.
Насправді, повторний запуск (скажімо так, "apache" під великим навантаженням, швидше за все, відправить блоки, що належать іншим службам, прямо на диск. Так, так, "apache" покращиться на короткий час, але "mysql" може страждати .. принаймні, поки ядро не змусить їх страждати однаково, коли просто не вистачає достатньої фізичної пам'яті.
Додайте більше пам’яті або розділіть вимогливих malloc()
споживачів :) Це не просто фрагментація, на яку потрібно дивитися.
Спробуйте vmstat
отримати огляд того, що насправді зберігається де.