Sto rispondendo al tag linux . La mia risposta è specifica solo per Linux .
Sì, le pagine enormi sono più soggette alla frammentazione. Ci sono due viste della memoria, quella che il tuo processo ottiene (virtuale) e quella che il kernel gestisce (reale). Più una pagina è grande, più sarà difficile raggruppare (e mantenerlo con) i suoi vicini, specialmente quando il tuo servizio è in esecuzione su un sistema che deve supportare anche altri che, per impostazione predefinita, allocano e scrivono su molta più memoria di loro finiscono per usare.
La mappatura del kernel degli indirizzi (reali) concessi è privata. C'è un ottimo motivo per cui userspace li vede mentre il kernel li presenta, perché il kernel deve essere in grado di sovraccaricare senza confondere lo spazio utente. Il tuo processo ottiene uno spazio di indirizzi "Disneyfied" piacevole e contiguo in cui lavorare, ignaro di ciò che il kernel sta effettivamente facendo con quel ricordo dietro le quinte.
Il motivo per cui si notano prestazioni degradate su server a esecuzione prolungata è molto probabilmente dovuto al fatto che i blocchi allocati che non sono stati esplicitamente bloccati (ad es. mlock()
/ mlockall()
O posix_madvise()
) e che non sono stati modificati da un po 'di tempo sono stati pagati , il che significa che il servizio scivola su disco quando deve leggere loro. La modifica di questo comportamento rende il tuo processo un cattivo vicinato , motivo per cui molte persone collocano il loro RDBMS su un server completamente diverso da web / php / python / ruby / qualunque cosa. L'unico modo per risolverlo, in modo sano, è ridurre la concorrenza per blocchi contigui.
La frammentazione è davvero evidente (nella maggior parte dei casi) quando la pagina A è in memoria e la pagina B è passata allo scambio. Naturalmente, riavviare il servizio sembrerebbe "curare" questo, ma solo perché il kernel non ha ancora avuto l'opportunità di eliminare il processo "(ora) blocchi appena allocati entro i limiti del suo rapporto di sovraccarico.
In effetti, il riavvio (diciamo) di 'apache' con un carico elevato probabilmente invierà blocchi di proprietà di altri servizi direttamente sul disco. Quindi sì, 'apache' migliorerebbe per un breve periodo, ma 'mysql' potrebbe soffrire .. almeno fino a quando il kernel non li farà soffrire ugualmente quando c'è semplicemente una mancanza di memoria fisica ampia.
Aggiungi più memoria o dividi i malloc()
consumatori esigenti :) Non è solo la frammentazione che devi guardare.
Prova vmstat
a ottenere una panoramica di ciò che viene effettivamente archiviato dove.