Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: buforowanie wyjścia i zniknięcia ramu
Forum PHP.pl > Forum > PHP
pearl1985
Witam was!

Czy spotkał się ktoś z was z bardzo niecodziennym problemem tzn. Podczas używania buforowania wyjścia oraz definiowania w metodzie klasy funkcji lambda, nieoczekiwanie po wykonaniu wielu wielu pętli znika nagle pamięć dostępna dla skryptu?

Jest to dla mnie bardzo dziwne zjawisko, bo poniższą klasę która napisałem aby ukazać problem który zauważyłem wykorzystuję jako template, gdzie przed include pliku php (szablon) robię dwie funkcje lamba, które służą mi do komunikacji z klasą języków itp.

Aby zrozumieć w czym rzecz przedstawiam poniżej, kod w którym owy błąd się pojawia.

  1. <?php
  2. class example
  3. {
  4. function test_remove_lambda()
  5. {
  6. $var = create_function('', '$a = 1;$b=2;$c=$a+$b;');
  7. $var();
  8. unset($var);
  9. }
  10. }
  11. $example = new example;
  12.  
  13. echo 'Memory limit: '.ini_get('memory_limit')."\n";
  14. echo 'Usage: '. round(memory_get_usage()/1024/1024, 1)."\n";
  15. echo 'Peak:'. round(memory_get_peak_usage()/1024/1024, 1);
  16. echo "\n";
  17.  
  18. //Użycie pamięci równe 0.1 lub 0
  19.  
  20. for($i=0;$i<=10000;$i++)
  21. {
  22. $example->test_remove_lambda();
  23. }
  24.  
  25. echo 'Results after remove lambda'."\n";
  26. echo 'Memory limit: '.ini_get('memory_limit')."\n";
  27. echo 'Usage: '. round(memory_get_usage()/1024/1024, 1)."\n";
  28. echo 'Peak:'. round(memory_get_peak_usage()/1024/1024, 1);
  29. echo "\n";
  30.  
  31. // po wykonaniu się owej pętli, gdzie w ogóle nie składuję danych do zmiennej itp. rzeczy nagle zużywam ok 9mb
  32. ?>


Poniżej przedstawiam wynik obliczeń (pierwsze uruchomienie):
CODE
Memory limit: 128M
Usage: 0.1
Peak:0.1
Results after remove lambda
Memory limit: 128M
Usage: 8.4
Peak:8.5


Kolejne uruchomienia skryptu:
CODE
Memory limit: 128M
Usage: 0
Peak:0
Results after remove lambda
Memory limit: 128M
Usage: 8.4
Peak:8.5
szagi3891
Istotnie to jest dziwne. Ale to raczej nie zależy od funkcji buforujących bo usunąłem je i otrzymałem bardzo podobne rezultaty. Tylko że u mnie na wyjściu wyniki były następujące :

Results after remove lambda
Memory limit 128M
Usage 12
Peak: 12

pogooglowałem i znalazłem komentarz z manuala :


Beware when using anonymous functions in PHP as you would in languages like Python, Ruby, Lisp or Javascript. As was stated previously, the allocated memory is never released; they are not objects in PHP -- they are just dynamically named global functions -- so they don't have scope and are not subject to garbage collection.

So, if you're developing anything remotely reusable (OO or otherwise), I would avoid them like the plague. They're slow, inefficient and there's no telling if your implementation will end up in a large loop. Mine ended up in an iteration over ~1 million records and quickly exhasted my 500MB-per-process limit.


Chyba lepiej będzie jak zrezygnujesz z funkcji anonimowych i zastąpisz to jakimś innym rozwiązaniem.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.