Jak ograniczyć wykorzystanie pamięci aplikacji?

10

Spędziłem 2 godziny na czytaniu pytań na ten temat, ale nadal istnieje pewne nieporozumienie.

Mam ten proces:

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND    
root 1452 0.4 1.8 1397012 19308 ? Sl 04:23 3:48 ./transaction_server

To pokazuje, że wykorzystuje 19.3Mbpamięć rezydentną systemu (nie mam pliku wymiany), wokół 1.8%całej 1GBpamięci systemowej. Rozmiar wirtualny to 1.39GB?!?. Przeczytałem, że ulimit -mto nie działa. Ludzie używają ulimit -vnp. Ustawienia wirtualnej pamięci dla procesu. Czy ta pamięć wirtualna jest wymieniona na liście VSZ ps? Jaką wartość powinienem ustawić, jeśli chcę ograniczyć ten proces do użycia 100MBmaksymalnie pamięci systemowej. Przeczytałem dokumentację setrlimiti wydaje się to uzasadnione:

RLIMIT_AS
        This  is  the maximum size of a process' total available memory, 
        in bytes. If this limit is exceeded, the malloc() and mmap() 
        functions shall fail with errno set to [ENOMEM]. In addition, 
        the automatic stack growth fails with the effects outlined above.

Ale w innych wersjach dokumentacji ten RLIMIT_ASparametr określa rozmiar pamięci wirtualnej. Jaka jest prawda?

Dragomir Iwanow
źródło
Proszę zwrócić uwagę na formatowanie postów.
rozcietrzewiacz

Odpowiedzi:

6

Tak, VSZ to pamięć wirtualna. Co do RLIMIT_AS, gdzie znalazłeś cytowany powyżej akapit? Ponieważ setrlimit (2) jest wywołaniem systemowym Linuksa, nie widzę, jak mógłby monitorować malloc (3), funkcję biblioteki. Zamiast tego może działać tylko z brk (2), sbrk (2) i mmap (2) - tak sugeruje również jego manpage (sprawdzone w Scientific Linux). Jednak całkowita ilość pamięci wymagana przez te funkcje to pamięć wirtualna, więc RLIMIT_AS rzeczywiście ogranicza pamięć wirtualną. (Jest to znowu zgodne ze stroną man setrlimit (2).)

Niestety nie można ograniczyć RSS pod Linuksem (byłoby to ulimit -m). Możesz spróbować ulimit -d(RLIMIT_DATA), ale to zignoruje mmap (2), zwykle używany do dużych alokacji. Inną możliwością byłoby ograniczenie pamięci wirtualnej, ale przy tak dużej różnicy między RSS a VSZ może to być trudne.

Ansgar Esztermann
źródło
Dziękuję za Twoją odpowiedź. Akapit pochodzi ze setrlimitstrony manuala. IEEE/The Open Group 2003 GETRLIMIT(3P)Jak to psmożliwe, że pokazuje mi RSS, ale jądro nie może narzucać ograniczeń?
Dragomir Iwanow
6
Według Alana Coxa ma to historyczne przyczyny: obliczanie RSS było drogie, więc egzekwowanie limitu spowodowałoby duże obciążenie jądra; źródło: linux.derkeiler.com/Mailing-Lists/Kernel/2006-01-01/msg03306.html . Zobacz także stackoverflow.com/questions/3043709/…
Ansgar Esztermann
Widzę. Chyba poszedłbym ulimit -dwtedy. Aplikacja została napisana przeze mnie i nie korzystałem mmap().
Dragomir Iwanow
2
Nie, zwykle nie (ani sbrk ()), ale może malloc ().
Ansgar Esztermann
Widzę. To bardzo niefortunne. Zatem rozwiązaniem tego pytania jest albo cgroups, albo sondowanie wykorzystania pamięci za pomocą jakiegoś języka skryptowego.
Dragomir Iwanow
3

Wiele procesów współdzieli część pamięci z innymi procesami, np. Libc jest używany przez prawie każdy proces, ale mapowany w pamięci tylko raz, ale liczy się to do wykorzystania pamięci wirtualnej każdego procesu. Ograniczenie użycia pamięci, które jest używane tylko przez określony proces (głównie RSS), można wykonać za pomocą cgroups. Zobacz odpowiedzi na temat Ograniczania całkowitych zasobów (pamięci) procesu i jego dzieci, aby dowiedzieć się, jak to zrobić. Ograniczy to całkowitą pamięć procesu i jego dzieci.

JanKanis
źródło