Odpowiadam na tag linux . Moja odpowiedź dotyczy tylko Linuksa .
Tak, ogromne strony są bardziej podatne na fragmentację. Istnieją dwa widoki pamięci, jeden tworzony przez proces (wirtualny) i ten, którym jądro zarządza (rzeczywisty). Im większa dowolna strona, tym trudniej będzie pogrupować (i utrzymać ją) sąsiadów, szczególnie gdy twoja usługa działa w systemie, który również musi wspierać innych, którzy domyślnie przydzielają i zapisują znacznie więcej pamięci niż oni faktycznie używam.
Mapowanie jądra (rzeczywistych) przyznanych adresów jest prywatne. Jest bardzo dobry powód, dla którego przestrzeń użytkownika widzi je tak, jak przedstawia je jądro, ponieważ jądro musi być w stanie nadkomitować bez mylenia przestrzeni użytkownika. Twój proces staje się przyjemny, ciągły przestrzeń adresową „Disneyfied”, w której można pracować, nieświadomy tego, co jądro robi z tą pamięcią za kulisami.
Powód, dla którego widzisz obniżoną wydajność na długo działających serwerach, jest najprawdopodobniej dlatego, że przydzielone bloki, które nie zostały wyraźnie zablokowane (np. mlock()
/ mlockall()
Lub posix_madvise()
) i nie zostały zmodyfikowane przez jakiś czas, zostały stronicowane , co oznacza, że Twoja usługa przesuwa się na dysk, gdy musi czytać im. Zmodyfikowanie tego zachowania powoduje, że proces jest złym sąsiadem , dlatego wiele osób umieszcza RDBMS na zupełnie innym serwerze niż web / php / python / ruby / cokolwiek. Jedynym sposobem, aby to naprawić, jest rozsądnie, zmniejszyć konkurencję dla sąsiadujących bloków.
Fragmentacja jest naprawdę zauważalna (w większości przypadków), gdy strona A jest w pamięci, a strona B została przeniesiona do zamiany. Oczywiście ponowne uruchomienie usługi wydawałoby się „wyleczyć” to, ale tylko dlatego, że jądro nie miało jeszcze okazji przeskoczyć procesu (obecnie) nowo przydzielonym blokom w ramach swojego współczynnika nadmiaru.
W rzeczywistości ponowne uruchomienie (powiedzmy) „apache” pod dużym obciążeniem prawdopodobnie spowoduje wysłanie bloków należących do innych usług bezpośrednio na dysk. Tak więc „apache” poprawiłoby się na krótki czas, ale „mysql” może cierpieć ... przynajmniej do czasu, aż jądro sprawi, że będą cierpieć tak samo, gdy po prostu brakuje wystarczającej pamięci fizycznej.
Dodaj więcej pamięci lub podziel się wymagającymi malloc()
klientów :) Nie chodzi tylko o fragmentację, na którą trzeba patrzeć.
Spróbuj vmstat
uzyskać przegląd tego, co faktycznie jest przechowywane.