2016-07-28 15 views
8

Zauważyłem, że istnieje znaczna różnica między tym, co top lub ps zgłasza jako użycie pamięci dla procesu PHP, w porównaniu do tego, co sam proces uważa za użytek (z memory_get_usage).Ile pamięci faktycznie używa PHP?

Ile pamięci faktycznie wykorzystuje proces?

Kiedy uruchomiony następujący kod wraz z jednym z moich aplikacji:

echo "Memory usage: " . pretty_bytes(memory_get_usage()) . PHP_EOL; 
echo "Peak memory usage: " . pretty_bytes(memory_get_peak_usage()) . PHP_EOL; 
echo "'Actual' memory usage: " . pretty_bytes(memory_get_usage(true)) . PHP_EOL; 
echo "'Actual' peak memory usage: " . pretty_bytes(memory_get_peak_usage(true)) . PHP_EOL; 

$ps_output = exec("ps --pid " . getmypid() . " --no-headers -o rss"); 

echo "'Memory usage according to ps: " . pretty_bytes(intval($ps_output) * 1000); 

Wyjście w przypadkowym miejscu był:

Memory usage: 4.77 MB 
Peak memory usage: 4.99 MB 
'Actual' memory usage: 5.00 MB 
'Actual' peak memory usage: 5.00 MB 
Memory usage according to ps: 17.66 MB 

W moim przypadku jest to problemem, bo” m działa dość wielu robotników i demonów.

Po ustawieniu limitu pamięci PHP na np. 128 MB dla każdego z tych demonów, procesy zostaną zabite dopiero po osiągnięciu 128 MB według własnych pomiarów PHP. Jednak zgodnie z ps, procesy będą zużywać około 200 MB każdy do tego czasu.

Odpowiedz

2

Należy podkreślić, co dokładnie wartości podane przez ps i memory_get_usage(true) są.

ps -o rss zgłasza faktyczny Resident Set Size. Poleganie na tej wartości jest dość pułapką, ponieważ nie obejmuje ona ostatecznie zamienionej pamięci. Ogólnie rzecz biorąc, chcesz uzyskać unikalny rozmiar , , który jest w zasadzie niewspieraną pamięcią (spójrz na tę informację pod adresem smem(8)). Jest to ilość wolnej pamięci, którą jądro faktycznie zmapowało strony dla tego procesu, tj. Fizycznie zaprezentuje nieudostępnioną pamięć w pamięci RAM lub plikach swap. Jest to tak blisko, jak tylko można uzyskać "rzeczywiste" użycie pamięci. [Zobacz także /proc/$PID/smaps, aby uzyskać szczegółowy przegląd, jak wspomniano w odpowiedzi IVO GELOV, w której można technicznie policzyć pamięć, którą chcesz zliczyć, parsując ten wirtualny plik.]

Jeśli chodzi o memory_get_usage(), to raportuje pamięć sterty faktycznie przydzieloną przez systemy przy użyciu wewnętrznego menedżera pamięci PHP. Oznacza to, że biblioteki, które bezpośrednio korzystają z innych menedżerów pamięci systemu (mmap(2) lub malloc(3)), nie ujawniają w tym miejscu wykorzystania pamięci. [Jest to na przykład dlaczego mysqlnd wykazuje znacznie zużycie pamięci podczas libmysqlclient nie robi. - korzysta on malloc() wewnętrznie]

Jeśli zdasz true jako pierwszy parametr, czyli memory_get_usage(true), zwraca całkowitą ilość pamięci wewnętrznej menedżera pamięci PHP poprosił o system. Liczba ta ogólnie jest nieznaczna, ale niewiele wyższa niż memory_get_usage(false). Jest to również liczba, z którą porównywane jest ustawienie INI memory_limit.

Jeśli chcesz sprawdzić, ile robotników możesz uruchomić, zwróć uwagę, że PHP nie udostępnia dużo pamięci, z wyjątkiem tego, że jądro może współdzielić pamięć bibliotek i opcache, które współużytkują struktury (kody opcyjne, informacje o klasach itp.). Dlatego pamięć współdzielona nie powinna być dla ciebie ważna. Najważniejszą wartością dla Ciebie powinno być więc USS.

+0

Dzięki @bwoebi Odpowiedź ta i Ivo dały nam wystarczający wgląd w problem rozwiązać problem. – Robbert

6

memory_get_usage zgłasza pamięć przydzieloną przez proces PHP do uruchomienia skryptu. ps raportuje pamięć używaną przez sam proces PHP, który zawiera pamięć używaną dla twojego skryptu. Proces PHP wykorzystuje wiele zewnętrznych bibliotek, które wszystkie mogą alokować swoją pamięć bez znajomości procesu PHP.

Tak więc memory_get_usage i ps z natury mierzą różne rzeczy i powinny podawać różne liczby. Wszystko sprowadza się do tego, jak definiujesz "rzeczywiste użycie pamięci". Rozumiem, że w twoim przypadku bardziej interesuje Cię wykorzystanie pamięci w procesie PHP. Wtedy dane wyjściowe z ps są bardziej odpowiednie dla Ciebie. Ale możesz łatwo stwierdzić, że nawet wartość RSS zgłoszona przez ps nie jest tak czarno-biała w świecie nowoczesnych systemów operacyjnych i współużytkowanych wspomnień.

Zobacz także:

+0

Dzięki Erki. To był dobry początek, ale wciąż brakowało nam trochę szczegółów, które @bwoebi był w stanie dostarczyć w swojej odpowiedzi. – Robbert

2

można znaleźć ciekawe rzeczy, gdy problem jeden z tych poleceń:

cat /proc/PID_NUMBER/smaps 
pmap -d PID_NUMBER 
+0

Niektóre tajne wyniki bez interpretacji (choć potencjalnie edukowanie) prawdopodobnie nie jest właściwym podejściem do SO. ; o) – Jakumi

+0

Dodatkowe informacje są dostępne w wielu miejscach, takich jak –

+0

, które mogą być bardzo dobre, ale jeśli nie masz linku do wielu z tych miejsc, Twoja odpowiedź nie dostarcza żadnych wglądów. – Jakumi

Powiązane problemy