Zostało to wspomniane na stronie instrukcji unset w 2009 roku :
unset()
robi dokładnie to, co mówi jego nazwa - odznacz zmienną. Nie wymusza natychmiastowego zwolnienia pamięci. Śmieciarka PHP zrobi to, gdy zobaczy pasowanie - z zamiarem, jak tylko te cykle procesora i tak nie będą potrzebne, lub tak późno, jak wcześniej skryptowi zabraknie pamięci, cokolwiek nastąpi wcześniej.
Jeśli to robisz $whatever = null;
, przepisujesz dane zmiennej. Być może pamięć zostanie zwolniona / zmniejszona szybciej, ale może ukraść cykle procesora z kodu, który naprawdę ich potrzebuje wcześniej, co powoduje dłuższy całkowity czas wykonania.
(Od 2013 r. unset
Ta strona podręcznika nie zawiera już tej sekcji)
Zauważ, że do php5.3, jeśli masz dwa obiekty w odwołaniu cyklicznym , takim jak relacja rodzic-dziecko, wywołanie unset () na obiekcie nadrzędnym nie zwolni pamięci używanej dla odwołania rodzica w obiekcie potomnym. (Pamięć nie zostanie również zwolniona, gdy obiekt nadrzędny zostanie wyrzucony do pamięci). ( Błąd 33595 )
Pytanie „ różnica między unset a = null ” wyszczególnia niektóre różnice:
unset($a)
usuwa również $a
z tablicy symboli; na przykład:
$a = str_repeat('hello world ', 100);
unset($a);
var_dump($a);
Wyjścia:
Notice: Undefined variable: a in xxx
NULL
Ale kiedy $a = null
jest używany:
$a = str_repeat('hello world ', 100);
$a = null;
var_dump($a);
Outputs:
NULL
Wygląda na $a = null
to, że jest nieco szybszy niż jego unset()
odpowiednik: aktualizacja wpisu tablicy symboli wydaje się szybsza niż jego usunięcie.
- przy próbie użycia nieistniejącej
unset
zmiennej ( ) zostanie wyzwolony błąd, a wartość wyrażenia zmiennej będzie zerowa. (Bo co jeszcze powinien zrobić PHP? Każde wyrażenie musi mieć jakąś wartość.)
- Zmienna z przypisanym null jest jednak nadal całkowicie normalną zmienną.
$whatever
wskazuje na obiekt,$whatever = null
zastępuje wskaźnik, a nie sam obiekt, więc działa on w zasadzie tak samo jakunset()
.unset
nie jest właściwie funkcją, ale konstrukcją języka . To nie jest więcej wywołanie funkcji niż areturn
lub aninclude
.Oprócz problemów z wydajnością, użycie
unset
sprawia, że intencje twojego kodu są znacznie wyraźniejsze.źródło
unset
jakoUnSeT
. Społeczność zdecydowała się na małe litery ze względu na styl, ale inne obudowy nadal działają.Wykonując unset () na zmiennej, zasadniczo zaznaczyłeś zmienną dla „odśmiecania” (PHP tak naprawdę jej nie ma, ale na przykład dla dobra), więc pamięć nie jest natychmiast dostępna. Zmienna nie mieści już danych, ale stos pozostaje w większym rozmiarze. Wykonanie metody zerowej powoduje spadek danych i prawie natychmiast zmniejsza pamięć stosu.
To było z własnego doświadczenia i innych. Zobacz komentarze funkcji unset () tutaj .
Osobiście używam unset () między iteracjami w pętli, aby nie musiałem opóźniać wielkości stosu. Dane zniknęły, ale pozostał ślad. Przy następnej iteracji pamięć jest już pobierana przez php, a zatem szybciej inicjuje następną zmienną.
źródło
Wydaje się, że „= null” jest szybszy.
Wyniki PHP 5.4:
Wyniki PHP 5.3:
Wyniki PHP 5.2:
Wyniki PHP 5.1:
Z PHP 5.0 i 4.4 wszystko zaczyna wyglądać inaczej.
5.0:
4.4:
Pamiętaj, że microtime (prawda) nie działa w PHP 4.4, więc musiałem użyć przykładu microtime_float podanego w php.net/microtime / Przykład # 1.
źródło
unset
jest szybsza. Mam test, który później sprawdza istnienie wunset
sprawie. W tym teście ustawienie tonull
jest nieznacznie szybsze. Test: pastebin.com/fUe57C51gc_collect_cycles
przed uruchomieniem stopera, aby uzyskać dokładniejsze wyniki.To robi różnicę w przypadku elementów tablicy.
Rozważ ten przykład
Tutaj kluczowy „test” nadal istnieje. Jednak w tym przykładzie
klucz już nie istnieje.
źródło
Działa w inny sposób dla zmiennych kopiowanych przez odniesienie:
źródło
Jeśli chodzi o obiekty, szczególnie w scenariuszu z leniwym ładowaniem, należy wziąć pod uwagę, że moduł wyrzucania elementów bezużytecznych działa w bezczynnych cyklach procesora, więc zakładając, że masz kłopoty, gdy ładuje się wiele obiektów, mała kara czasowa rozwiąże zwolnienie pamięci.
Użyj time_nanosleep, aby umożliwić GC gromadzenie pamięci. Pożądane jest ustawienie zmiennej na null.
Testowane na serwerze produkcyjnym, początkowo zadanie zużywało 50 MB, a następnie zostało zatrzymane. Po użyciu nanosnu 14 MB było stałym zużyciem pamięci.
Należy powiedzieć, że zależy to od zachowania GC, które może się zmieniać z wersji PHP na wersję. Ale działa dobrze na PHP 5.3.
na przykład. ta próbka (kod pochodzi z kanału google VirtueMart2)
źródło
Nadal mam co do tego wątpliwości, ale wypróbowałem to w swoim skrypcie i używam xdebug, aby wiedzieć, jak wpłynie to na użycie pamięci przez moją aplikację. Skrypt jest ustawiony dla mojej funkcji w następujący sposób:
I dodaję nieustawiony tuż przed
return
kodem i daje mi: 160200, a następnie próbuję go zmienić$sql = NULL
i daje mi: 160224 :)Ale jest coś wyjątkowego w tym porównaniu, gdy nie używam unset () lub NULL, xdebug daje mi 160144 jako użycie pamięci
Tak więc myślę, że podanie wiersza do użycia unset () lub NULL doda proces do twojej aplikacji i lepiej pozostanie pochodzenie z twoim kodem i zmniejszenie zmiennej, której używasz tak efektywnie, jak to możliwe.
Popraw mnie, jeśli się mylę, dzięki
źródło
Stworzyłem nowy test wydajności dla
unset
i=null
, ponieważ, jak wspomniano w komentarzach, tutaj napisany jest błąd (odtwarzanie elementów). Użyłem tablic, jak widzisz, nie miało to teraz znaczenia.Ale mogę go przetestować tylko na serwerze PHP 5.5.9, tutaj wyniki: - zajęło 4,4571571350098 sekund - zajęło 4,4425978660583 sekund
Wolę
unset
ze względu na czytelność.źródło
PHP 7 już pracuje nad takimi problemami z zarządzaniem pamięcią i jej ograniczeniem do minimalnego zużycia.
PHP 7.1 Outpu:
zajęło 0.16778993606567 sekund zajęło 0.16630101203918 sekund
źródło
unset
kod, jeśli nie zwolnienie natychmiastowej pamięci, jest nadal bardzo pomocne i dobrą praktyką byłoby to robić za każdym razem, gdy przekazujemy kroki kodu przed wyjściem z metody. zwróć uwagę, że nie chodzi o uwolnienie natychmiastowej pamięci. pamięć bezpośrednia jest przeznaczona na procesor, co z pamięcią dodatkową, którą jest RAM.i dotyczy to również zapobiegania wyciekom pamięci.
patrz ten link http://www.hackingwithphp.com/18/1/11/be-wary-of-garbage-collection-part-2
Od dłuższego czasu używam unset.
lepsza praktyka taka jak w kodzie, aby natychmiast rozbroić wszystkie zmienne, które były już używane jako tablica.
i
just unset($data);
uwolnić wszystkie zmienne użycie.proszę zobaczyć pokrewny temat do rozbrojenia
Jak ważne jest rozbrajanie zmiennych w PHP?
[pluskwa]
źródło
Dla przypomnienia, z wyłączeniem czasu, który zajmuje:
Powraca
Wniosek, zarówno zerowa, jak i nieustawiona wolna pamięć, zgodnie z oczekiwaniami (nie tylko na końcu wykonywania). Ponadto ponowne przypisanie zmiennej zachowuje wartość dwukrotnie w pewnym momencie (520216 w porównaniu z 438352)
źródło