Co oznacza rozmiar pamięci wirtualnej u góry?


124

Pracuję, topaby monitorować wydajność serwera, a 2 moje procesy Java pokazują pamięć wirtualną do 800 MB-1 GB. Czy to źle?

Co oznacza pamięć wirtualna?

Aha btw, mam zamianę 1 GB i pokazuje 0% zużytego. Więc jestem zmieszany.

Proces Java = 1 serwer Tomcat + mój własny demon java Server = Ubuntu 9.10 (karmic)


Odpowiedzi:


142

Pamięć wirtualna niekoniecznie jest pamięcią. Na przykład, jeśli pamięć procesu mapuje duży plik, plik jest faktycznie przechowywany na dysku, ale w dalszym ciągu zajmuje „przestrzeń adresową”.

Przestrzeń adresowa (tj. Pamięć wirtualna na liście procesów) nic nie kosztuje; to nie jest prawdziwe. Rzeczywista jest kolumna RSS (RES), która jest pamięcią rezydentną. Tak wiele pamięci zajmuje proces.

Ale nawet to nie jest cała odpowiedź. Jeśli proces wywołuje fork (), dzieli się na dwie części i obie początkowo udostępniają wszystkie swoje kanały RSS. Więc nawet jeśli RSS miałby początkowo 1 GB, wynikiem po rozwidleniu byłyby dwa procesy, każdy z RSS o wielkości 1 GB, ale nadal używałbyś tylko 1 GB pamięci.

Zdezorientowany? Oto, co naprawdę musisz wiedzieć: użyj freepolecenia i sprawdź wyniki przed i po uruchomieniu programu (w +/- buffers/cachewierszu). Różnica polega na tym, ile nowej pamięci używał nowo uruchomiony program.


2
„Sprawdź wyniki przed i po uruchomieniu programu”, alternatywnie użyj USS (Unique Set Size) w postaci zwróconej przez smem.
Hubert Kario

Czy istnieje narzędzie, które zapewnia rzeczywistą ilość używanej pamięci, narzędzia, które nie są stronami trzecimi.
CMCDragonkai

@CMCDragonkai Tak, za darmo.
deviantfan

1
Jeśli uruchomię proces Java java -Xmx16g RunLong, który zarezerwowałby pamięć 16 Gb dla procesu Java, to na VIRTgórze wydaje się, że 16 Gb jest liczony. W takim przypadku, jaki jest typ tej pamięci 16 Gb, czy jest to pamięć zmapowana lub ...?
Eric Wang,

1
@EricWang, ta pamięć nie jest mapowana. To tylko prośba do OS o zarezerwowanie pamięci, która może być potrzebna później (być może nigdy). (Przynajmniej) w systemie Linux, jest to wywołanie mmap z flagami MAP_NORESERVE i PROT_NONE (patrz os :: pd_reserve_memory wywołuje anon_mmap: github.com/AdoptOpenJDK/openjdk-jdk11u/blob/… ); domyślnie nie jest alokowana pamięć - jest to robione dopiero w momencie, gdy program naprawdę potrzebuje pamięci do spełnienia żądań alokacji obiektów.
Juraj Martinka

23

Z górnej strony podręcznika (1):

o: VIRT  --  Virtual Image (kb)
      The  total  amount  of  virtual  memory  used  by the task.  It
      includes all code, data and shared libraries  plus  pages  that
      have been swapped out.

      VIRT = SWAP + RES.

Gdzie RES oznacza pamięć RESident (używana pamięć fizyczna).

Właściwie to już nie jest poprawne. Kiedy mówi „zamień”, obejmuje to również pliki, które program zamapował na swoją przestrzeń adresową, która może, ale nie musi, faktycznie zużywać prawdziwą pamięć RAM. Ta pamięć ma kopię zapasową pliku, ale tak naprawdę nie jest wymienna.

VIRT obejmuje także strony, które zostały przydzielone, ale do niczego jeszcze nie wykorzystane. Każda strona w tym stanie jest odwzorowana na jądro strony zerowej (genialna koncepcja - powinieneś to sprawdzić), więc wyświetla się w VIRT, ale tak naprawdę nie zużywa żadnej pamięci.


2
Cóż, to interesujące, więc VIRT = SWAP + RES, dlaczego moje użycie SWAP wynosi zero, podczas gdy pamięć wirtualna dla 2 procesów Java jest bliska 1 GB?
kapso

w zasadzie Najlepsze programy ... Zamiana: 1048568k łącznie, 0k używane, 1048568k wolne, 505728k buforowane
kapso

15
@ user42159 Ta odpowiedź jest ZŁA! Nie ma „VIRT = SWAP + RES” na górze człowieka! -m : VIRT/USED toggle Reports USED (sum of process rss and swap total count) instead of VIRT. Szkoda, że ​​nie mogę głosować za tą odpowiedzią.
duleshi,

3
Ta odpowiedź jest niepoprawna. UŻYWANE = Res + Swap Size (z góry Zarządzanie polami, dostępne po naciśnięciu klawisza f, gdy jest na górze. Również z górnej strony podręcznika).
Jason S,

14

To wyjaśnienie Mugurel Sumanariu było dla mnie bardzo jasne:

VIRToznacza wirtualny rozmiar procesu, który jest sumą pamięci, której faktycznie używa, pamięci, którą zamapował na siebie (na przykład RAM karty graficznej dla serwera X), plików na dysku, które zostały zamapowane na nim (większość szczególnie biblioteki współdzielone) i pamięć współdzielona z innymi procesami. VIRT reprezentuje ilość pamięci, jaką program jest w stanie uzyskać w chwili obecnej.

RESoznacza rozmiar rezydenta, który jest dokładnym odwzorowaniem ilości faktycznej pamięci fizycznej zużywanej przez proces. (Odpowiada to również bezpośrednio kolumnie% MEM.) Praktycznie zawsze będzie ona mniejsza niż rozmiar VIRT, ponieważ większość programów zależy od biblioteki C.

SHRwskazuje, jaka część rozmiaru VIRT jest rzeczywiście możliwa do udostępnienia (pamięć lub biblioteki). W przypadku bibliotek niekoniecznie oznacza to, że cała biblioteka jest rezydentem. Na przykład, jeśli program korzysta tylko z kilku funkcji w bibliotece, cała biblioteka jest odwzorowana i zostanie zliczona w VIRT i SHR, ale tylko części pliku biblioteki zawierające używane funkcje zostaną faktycznie załadowane i zliczone w ramach RES.


Być może chciałbym tylko powtórzyć „VIRT reprezentuje ilość pamięci, jaką program jest w stanie uzyskać w chwili obecnej”. do czegoś takiego jak „VIRT reprezentuje rozmiar całej przestrzeni adresowalnej programu w chwili obecnej”. OK, to nadal mogłoby używać polskiego. Ale chodzi o to, „ile pamięci” może sprawiać wrażenie, że dyskutujemy o pamięci RAM, gdy VIRT nie ma nic wspólnego z pamięcią RAM. W rzeczywistości duże programy często mają rozmiar VIRT, który jest kilkoma MULTIPLAMI całkowitego rozmiaru pamięci RAM systemu - ponieważ VIRT to prawie w całości regiony adresów oparte na plikach (AKA „dysk nie RAM”).
FeRD

5

Kolumna VIRT w wyjściu ps / top jest prawie nieistotna do pomiaru zużycia pamięci. Nie martw się o to. Pamięć VIRT o dużym obciążeniu Apache a pamięć RES

https://stackoverflow.com/questions/561245/virtual-memory-usage-from-java-under-linux-too-much-memory-used


Dzięki, zmartwiłem się i pomyliłem, ponieważ chociaż użycie wymiany wynosiło 0%, kolumna pamięci wirtualnej jest bardzo wysoka. A także mam tylko 1,7 GB całkowitej pamięci fizycznej 2,7 GB, podczas gdy pamięć wirtualna jest wysoka?
kapso

2

Linux obsługuje pamięć wirtualną, to znaczy użycie dysku jako rozszerzenia pamięci RAM, aby odpowiednio zwiększyć efektywny rozmiar pamięci użytecznej. Jądro zapisze zawartość aktualnie nieużywanego bloku pamięci na dysku twardym, aby pamięć mogła zostać wykorzystana do innego celu. Gdy oryginalna zawartość jest ponownie potrzebna, są one ponownie wczytywane do pamięci. Wszystko to jest całkowicie przejrzyste dla użytkownika; programy działające w systemie Linux widzą tylko większą ilość dostępnej pamięci i nie zauważają, że niektóre z nich znajdują się na dysku od czasu do czasu. Oczywiście, czytanie i zapisywanie na dysku twardym jest wolniejsze (rzędu tysiąc razy wolniej) niż używanie prawdziwej pamięci, więc programy nie działają tak szybko. Część dysku twardego używana jako pamięć wirtualna nazywana jest przestrzenią wymiany.

Linux może używać normalnego pliku w systemie plików lub oddzielnej partycji dla przestrzeni wymiany. Partycja wymiany jest szybsza, ale łatwiej jest zmienić rozmiar pliku wymiany (nie trzeba partycjonować całego dysku twardego i ewentualnie instalować wszystkiego od zera). Kiedy wiesz, ile potrzebujesz przestrzeni wymiany, powinieneś wybrać partycję wymiany, ale jeśli nie masz pewności, możesz najpierw użyć pliku wymiany, użyj systemu na chwilę, abyś mógł sprawdzić, ile wymiany masz potrzebujesz, a następnie utwórz partycję wymiany, gdy masz pewność co do jego rozmiaru.

Powinieneś także wiedzieć, że Linux pozwala na korzystanie z kilku partycji wymiany i / lub plików wymiany w tym samym czasie. Oznacza to, że jeśli tylko od czasu do czasu potrzebujesz nietypowej ilości przestrzeni wymiany, możesz w tym czasie ustawić dodatkowy plik wymiany, zamiast cały czas przydzielać całą kwotę.

Uwaga na temat terminologii systemu operacyjnego: informatyka zwykle rozróżnia między zamianą (zapisywanie całego procesu na przestrzeń wymiany) a stronicowaniem (pisanie tylko części o stałym rozmiarze, zwykle kilku kilobajtów jednocześnie). Przywoływanie jest zwykle bardziej wydajne i tak robi Linux, ale tradycyjna terminologia Linuksa mówi o zamianie.

Źródło: http://www.faqs.org/docs/linux_admin/x1752.html


1
Ta odpowiedź rozpowszechnia błędne przekonanie, że pamięć wirtualna jest taka sama jak wymiana lub stronicowanie. Używanie dysku jako rozszerzenia pamięci RAM poprzedza pamięć wirtualną. Istnieje wiele systemów (takich jak większość routerów SoHo), które mają pamięć wirtualną, ale nie używają dysku jako rozszerzenia pamięci RAM. (I to nie jest odpowiedź na pytanie PO, ponieważ nie używa żadnej zamiany.)
David Schwartz

2

VIRtualkolumna na górze odnosi się do superprzestrzeni (miejsca do zużycia) procesu, którego proces może nie brać w rzeczywistości w czasie wykonywania. Istnieje inna kolumna RESident, która odnosi się do faktycznej pamięci fizycznej / przestrzeni przydzielonej przez proces w czasie wykonywania.

Przyczynę różnicy między nimi można zrozumieć na przykładzie: jeśli proces korzysta z określonej biblioteki, wówczas rozmiar biblioteki również pomoże virtual-size. jednak ponieważ tylko część biblioteki byłaby używana (tj. niektóre metody w użyciu), więc to pomoże resident-size.

Zobacz więcej informacji


0

„VIRT” to po prostu przestrzeń adresowa, RES jest „rzeczywistą” pamięcią, ale „SHR” (= współużytkowana) ilość „RES” jest częścią RES, która jest współdzielona z innymi procesami. Tak więc w przypadku większości procesów uważam, że odjęcie SHR od RES daje ci ilość pamięci, którą naprawdę można przypisać do tego konkretnego procesu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.