Czy w PHP (lub rozszerzeniu PHP) jest funkcja sprawdzająca, ile pamięci zużywa dana zmienna? sizeof
po prostu podaje liczbę elementów / właściwości.
memory_get_usage
pomaga w tym, że daje mi rozmiar pamięci używanej przez cały skrypt. Czy istnieje sposób na zrobienie tego dla pojedynczej zmiennej?
Zauważ, że jest to na komputerze deweloperskim, więc ładowanie rozszerzeń lub narzędzi do debugowania jest możliwe.
Odpowiedzi:
Prawdopodobnie potrzebujesz profilera pamięci. Zebrałem informacje na ten temat, ale skopiowałem kilka ważnych rzeczy, które mogą ci pomóc.
Jak zapewne wiesz, Xdebug porzucił obsługę profilowania pamięci od wersji 2. *. Wyszukaj ciąg „usunięte funkcje” tutaj: http://www.xdebug.org/updates.php
Inne opcje profilera
php-memory-profiler
https://github.com/arnaud-lb/php-memory-profiler . Oto, co zrobiłem na moim serwerze Ubuntu, aby to włączyć:
A potem w moim kodzie:
Na koniec otwórz
callgrind.out
plik za pomocą KCachegrindKorzystanie z Google gperftools (zalecane!)
Przede wszystkim zainstaluj gperftools Google , pobierając najnowszy pakiet tutaj: https://code.google.com/p/gperftools/
Wtedy jak zawsze:
Teraz w twoim kodzie:
Następnie otwórz terminal i uruchom:
pprof utworzy nowe okno w istniejącej sesji przeglądarki, jak pokazano poniżej:
Xhprof + Xhgui (moim zdaniem najlepiej profiluje zarówno procesor jak i pamięć)
Dzięki Xhprof i Xhgui możesz również profilować użycie procesora lub tylko użycie pamięci, jeśli jest to obecnie Twój problem. To bardzo kompletne rozwiązanie, daje pełną kontrolę, a logi można zapisywać zarówno w mongo, jak iw systemie plików.
Więcej informacji można znaleźć tutaj .
Czarny ogień
Blackfire to profiler PHP stworzony przez SensioLabs, gości z Symfony2 https://blackfire.io/
Jeśli używasz Puphpet do skonfigurowania maszyny wirtualnej, z przyjemnością dowiesz się, że jest obsługiwana ;-)
Xdebug i śledzenie użycia pamięci
XDEBUG2 to rozszerzenie dla PHP. Xdebug umożliwia rejestrowanie wszystkich wywołań funkcji, w tym parametrów i zwracanie wartości do pliku w różnych formatach. Istnieją trzy formaty wyjściowe. Jeden jest pomyślany jako czytelny dla człowieka ślad, inny jest bardziej odpowiedni dla programów komputerowych, ponieważ jest łatwiejszy do przeanalizowania, a ostatni używa HTML do formatowania śladu. Możesz przełączać się między dwoma różnymi formatami za pomocą tego ustawienia. Przykład byłby dostępny tutaj
dla p
forp prosty, nieinwazyjny, zorientowany na produkcję, profiler PHP. Oto niektóre funkcje:
pomiar czasu i przydzielonej pamięci dla każdej funkcji
użycie procesora
plik i numer linii wywołania funkcji
dane wyjściowe w formacie Google Trace Event
podpis funkcji
grupowanie funkcji
aliasy funkcji (przydatne w przypadku funkcji anonimowych)
DBG
DBG to w pełni funkcjonalny debugger php, interaktywne narzędzie, które pomaga debugować skrypty php. Działa na produkcyjnym i / lub deweloperskim serwerze WEB i umożliwia debugowanie skryptów lokalnie lub zdalnie, z IDE lub konsoli, a jego funkcje to:
Zdalne i lokalne debugowanie
Jawna i niejawna aktywacja
Stos wywołań, w tym wywołania funkcji, dynamiczne i statyczne wywołania metod, wraz z ich parametrami
Nawigacja po stosie wywołań z możliwością oceny zmiennych w odpowiednich (zagnieżdżonych) miejscach
Wejdź / Wyjdź / Przejdź nad / Uruchom do funkcji kursora
Warunkowe punkty przerwania
Globalne punkty przerwania
Rejestrowanie błędów i ostrzeżeń
Wiele jednoczesnych sesji do równoległego debugowania
Obsługa frontonów GUI i CLI
Obsługiwane sieci IPv6 i IPv4
Wszystkie dane przesyłane przez debugger mogą być opcjonalnie chronione za pomocą SSL
źródło
Nie ma bezpośredniego sposobu na uzyskanie wykorzystania pamięci dla pojedynczej zmiennej, ale jak zasugerował Gordon, możesz użyć
memory_get_usage
. To zwróci całkowitą ilość przydzielonej pamięci, więc możesz użyć obejścia i zmierzyć użycie przed i po, aby uzyskać użycie jednej zmiennej. To trochę hakerskie, ale powinno działać.Zauważ, że nie jest to w żaden sposób niezawodna metoda, nie możesz być pewien, że nic innego nie dotyka pamięci podczas przypisywania zmiennej, więc powinno to być używane tylko jako przybliżenie.
W rzeczywistości można to przekształcić w funkcję, tworząc kopię zmiennej wewnątrz funkcji i mierząc wykorzystaną pamięć. Nie testowałem tego, ale w zasadzie nie widzę w tym nic złego:
źródło
$tmp = $var
utworzy płytką kopię. To nie przydzieli większej ilości pamięci, dopóki $ tmp nie zostanie zmodyfikowane.$tmp = unserialize(serialize($var))
; To połączyłoby powyższe podejście Aistiny.$var
jest już płytką kopią lub odniesieniem do tego, co zostało przekazane do funkcji, nie potrzebujesz$tmp
, ale możesz ponownie przypisać$var
. Spowoduje to zapisanie wewnętrznego odniesienia z$tmp
do$var
.$tmp
od$var
?Nie, nie ma. Ale możesz
serialize($var)
i sprawdzićstrlen
wynik dla przybliżenia.źródło
strlen(serialize(array(1,2,3)))
ma 30.W odpowiedzi do Tatu Ulmanensa odpowiedz:
Należy zauważyć, że
$start_memory
sam zajmie pamięć (PHP_INT_SIZE * 8
).Zatem cała funkcja powinna wyglądać następująco:
Przepraszam, że dodam to jako dodatkową odpowiedź, ale nie mogę jeszcze skomentować odpowiedzi.
Aktualizacja: * 8 nie jest zdefiniowana. Może to najwyraźniej zależeć od wersji php i prawdopodobnie od 64/32 bitów.
źródło
* 8
? Dzięki!PHP_INT_SIZE
bajtów, alePHP_INT_SIZE*8
. Możesz spróbować, wywołując tę funkcję, powinna ona zwrócić 0:function sizeofvar() { $start_memory = memory_get_usage(); return memory_get_usage() - $start_memory - PHP_INT_SIZE*8; }
8
nie wydaje się stały. Po twojej funkcji komentowania w moim systemie deweloperskim (PHP 5.6.19), zwraca-16
. Co ciekawe,php -a
wywołanie dwóch wierszy funkcji z funkcji daje różne wartości.Widzieć:
memory_get_usage()
- Zwraca ilość pamięci przydzielonej PHPmemory_get_peak_usage()
- Zwraca szczyt pamięci przydzielonej przez PHPPamiętaj jednak, że nie da ci to wykorzystania pamięci przez określoną zmienną. Ale możesz wywołać te funkcje przed i po przypisaniu zmiennej, a następnie porównać wartości. To powinno dać ci wyobrażenie o używanej pamięci.
Możesz także rzucić okiem na rozszerzenie PECL Memtrack , chociaż dokumentacji trochę brakuje, jeśli nie powiedzieć, praktycznie nie istnieje.
źródło
Możesz zdecydować się na obliczanie różnicy pamięci dla wartości zwracanej przez wywołanie zwrotne. To bardziej eleganckie rozwiązanie dostępne w PHP 5.3+.
źródło
Nie można retrospektywnie obliczyć dokładnego śladu zmiennej, ponieważ dwie zmienne mogą dzielić to samo przydzielone miejsce w pamięci
Spróbujmy podzielić pamięć między dwiema tablicami, widzimy, że przydzielenie drugiej tablicy kosztuje połowę pamięci pierwszej. Kiedy rozbroimy pierwszą, prawie cała pamięć jest nadal zajęta przez drugą.
Nie możemy więc wnioskować, że druga tablica zużywa połowę pamięci, ponieważ staje się fałszywa, gdy usuwamy pierwszą.
Aby uzyskać pełny obraz tego, jak alokowana jest pamięć w PHP i do czego służy, sugeruję przeczytanie następującego artykułu: Jak duże są naprawdę tablice (i wartości) PHP? (Podpowiedź: DUŻA!)
W sekcji Podstawy liczenia odniesień w dokumentacji PHP znajduje się również wiele informacji o wykorzystaniu pamięci, a odwołania liczą się do segmentu danych współdzielonych.
Przedstawione tutaj różne rozwiązania są dobre do przybliżeń, ale żadne nie poradzi sobie z subtelnym zarządzaniem pamięcią PHP.
Jeśli chcesz nowo przydzieloną przestrzeń po przydziale, musisz użyć jej
memory_get_usage()
przed i po przydziale, ponieważ używanie jej z kopią daje błędny obraz rzeczywistości.Pamiętaj, że jeśli chcesz zapisać wynik pierwszej
memory_get_usage()
, zmienna musi już istnieć wcześniej imemory_get_usage()
musi być nazwana poprzednio inną, a także każdą inną funkcją.Jeśli chcesz wywołać echo jak w powyższym przykładzie, twój bufor wyjściowy musi być już otwarty, aby uniknąć pamięci rozliczeniowej potrzebnej do otwarcia bufora wyjściowego.
Jeśli chcesz polegać na funkcji obliczającej wymaganą przestrzeń do przechowywania kopii zmiennej, poniższy kod zajmuje się różnymi optymalizacjami:
Zauważ, że rozmiar nazwy zmiennej ma znaczenie w przydzielonej pamięci.
Zmienna ma podstawowy rozmiar zdefiniowany przez wewnętrzną strukturę C używaną w kodzie źródłowym PHP. Wielkość ta nie zmienia się w przypadku liczb. W przypadku ciągów dodawałby długość ciągu.
Jeśli nie weźmiemy pod uwagę inicjalizacji nazwy zmiennej, wiemy już, ile używa zmienna (w przypadku liczb i łańcuchów):
(te liczby mogą się zmieniać w zależności od wersji PHP)
Musisz zaokrąglić do wielokrotności 4 bajtów ze względu na wyrównanie pamięci. Jeśli zmienna znajduje się w przestrzeni globalnej (nie wewnątrz funkcji), przydzieli również 64 dodatkowe bajty.
Więc jeśli chcesz użyć jednego z kodów na tej stronie, musisz sprawdzić, czy wynik za pomocą prostych przypadków testowych (ciągów lub liczb) jest zgodny z tymi danymi, biorąc pod uwagę wszystkie wskazania w tym poście (tablica $ _GLOBAL, pierwsze wywołanie funkcji, bufor wyjściowy, ...)
źródło
zvalue
,is_ref
i kopiowanie przy zapisie. Dziękuję Ci.Miałem podobny problem i rozwiązaniem, którego użyłem, było zapisanie zmiennej do pliku, a następnie uruchomienie na nim filesize (). Mniej więcej tak (nieprzetestowany kod):
To rozwiązanie nie jest zbyt szybkie, ponieważ obejmuje operacje we / wy dysku, ale powinno dać ci coś znacznie dokładniejszego niż sztuczki memory_get_usage. Zależy to tylko od wymaganej precyzji.
źródło
strlen
byłoby łatwiejsze.Nigdy nie próbowałem, ale ślady Xdebug z xdebug.collect_assignment s mogą wystarczyć.
źródło
źródło
Poniższy skrypt przedstawia całkowite użycie pamięci przez jedną zmienną.
Sprawdź to
http://www.phpzag.com/how-much-memory-do-php-variables-use/
źródło