Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

3 Stron V  < 1 2 3  
Reply to this topicStart new topic
> [PHP] Wyciek pamięci
com
post 8.02.2018, 17:56:29
Post #41





Grupa: Zarejestrowani
Postów: 3 033
Pomógł: 366
Dołączył: 24.05.2012

Ostrzeżenie: (0%)
-----


Ale jest, bo nie wywołany jest destruct na starym Exception wiec, gc nie może sprzątać, bo jak pamiętamy PHP zlicza referencje biggrin.gif
Go to the top of the page
+Quote Post
darko
post 9.02.2018, 23:36:39
Post #42





Grupa: Zarejestrowani
Postów: 2 885
Pomógł: 463
Dołączył: 3.10.2009
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


Jeśli masz znaczną ilość faili, to może przed próbą pobrania zawartości strony odczytaj samą wartość nagłówka HTTP i sprawdzaj czy to nie 404. mam na myśli coś takiego, pobierasz tylko nagłówki odpowiedzi serwera i wyciągasz sam kod http odpowiedzi:

  1. protected function _getHeaderResponseCode($url) {
  2. $handle = curl_init($url);
  3. curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
  4. curl_setopt($handle, CURLOPT_NOBODY, 1);
  5. $response = curl_exec($handle);
  6. $httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
  7. return $httpCode;
  8. }
  9.  
  10. // ...
  11.  
  12. if ($this->_getHeaderResponseCode($url) != 404) {
  13. $data = file_get_contents($url);
  14. }
  15.  
  16. // ...


--------------------
Nie pomagam na pw, tylko forum.
Go to the top of the page
+Quote Post
SmokAnalog
post 9.02.2018, 23:52:51
Post #43





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Darko, nie obraź się, ale wszystkie Twoje odpowiedzi w tym temacie (łącznie z powyższą) są idiotyczne. Sugerujesz teraz, żeby spowolnić cały crawler dwukrotnie tylko po to, żeby uniknąć wyjątku? Przecież wiadomo, że wąskim gardłem wszelkich webowych crawlerów jest czas odpowiedzi serwera zewnętrznego. Poczytaj ten temat i inne podobne tematy, żeby poznać konsolowe i crawlerowe zastosowanie PHP. Ubolewam nad tym, że przez całą noc crawluję zaledwie 20-30 tys. wyników, ale nieeee - spowolnię sobie to do 10-15 tys., żeby nie wyrzucać wyjątków. Yeah!

Jakbym już miał unikać wyjątków, to przecież mogę od razu użyć cURL-a, który wyjątków dla 404 nie wywala. Chciałem uprościć kod i nauczyć się czegoś więcej o zarządzaniu pamięcią w sytuacji wyrzucania wyjątków.

Ten post edytował SmokAnalog 9.02.2018, 23:53:21
Go to the top of the page
+Quote Post
darko
post 10.02.2018, 02:29:44
Post #44





Grupa: Zarejestrowani
Postów: 2 885
Pomógł: 463
Dołączył: 3.10.2009
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


To teraz Ty się nie obraź, bo już mnie lekko irytujesz swoją impertynencją w tym i nie tylko w tym temacie. Najpierw sam sobie tworzysz wyimaginowany problem i wprowadzasz ludzi, którzy chcą się wspólnie zmóżdzyć z Tobą w błąd, nie podając pełnego kodu, a jedynie jakieś wyrywki. Pewnie. Domyślamy się wszyscy, że masz swój error handler... Patrz! unset zwalnia pamięć! Eureka! Następnie drążysz temat zarządzania pamięcią, na które to dość specyficzne w PHP zarządzanie nie masz totalnie żadnego wpływu i głową muru nie przebijesz, by na końcu określić czyjąś wypowiedź jako idiotyczną. Świetnie. Bawmy się tak dalej.
Użyj curla i nie płacz, że wolno działa, albo, że skrypt zżera za dużo pamięci. Przez podejście takich ludzi, jak Ty, o społeczności skupionej wokół języka PHP jeszcze długo będzie się mówić źle i tylko źle.
Zamiast skupić się na użyteczności i przydatności kodu, a przede wszystkim na jego wartości biznesowej, lecisz na forum ze sztucznie stworzonym problemem, którego tak naprawdę nie ma.
Założę się, że nawet nie raczyłeś sprawdzić curlowego rozwiązania, ale z góry zakładasz, że będzie działało znacznie wolniej.
Poczytaj o curl_multi_init, curl_multi_exec, wykonywaniu jednoczesnym żądań korzystając z tzw. gniazd nieblokujących, asynchronicznie. Jakby to dobrze napisać, to ten Twój crawlerek będzie zapierdzielał jeszcze szybciej niż z kupą niepotrzebnych wyjątków i skopiowanym całym backtracem zupełnie niepotrzebnie. Jak znasz odrobinę języka C to polecam lekturę źródeł PHP, tam naprawdę więcej nauczysz się o zarządzaniu pamięcią, niż poprzez takie eksperymenty.
Zresztą - nawet jeśli ten crawler będzie ciut wolniejszy, to chyba lepiej troszkę wolniej, ale niech w ogóle działa i nie wali błędami niż crawler, który po prostu nie działa...
PHP jeszcze Cię wiele razy zaskoczy. Idiotyczne są takie pseudo problemy. Tyle z mojej strony, trzymaj się, buziaki, pozdrówki. ps. nie jesteś w stanie mnie obrazić.

Ten post edytował darko 10.02.2018, 02:38:35


--------------------
Nie pomagam na pw, tylko forum.
Go to the top of the page
+Quote Post
SmokAnalog
post 10.02.2018, 03:52:36
Post #45





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

Ostrzeżenie: (0%)
-----


No ciekawe jak przyśpieszysz w kodzie crawlera przysyłanie odpowiedzi ze źródła, na które nie masz wpływu. Coś tam Ci świta z zarządzaniem pamięci, ale sam się gubisz. Jeszcze przed chwilą mówiłeś, że PHP się nie nadaje do daemonów i crawlerów, co jest kompletną bzdurą.

Akurat unset w catch nie jest powszechnie znaną techniką, bo nie jest oczywistym faktem to co się dzieje z wyjątkami w pamięci.

Lepiej być impertynenckim niż niekompetentnym i wypowiadać się w tematach, o których się nie ma pojęcia, zamiast grzecznie czekać na odpowiedź kogoś, kto się zna.

A problem nie jest wyimaginowany. Bardzo często chce się zachować strukturę z wyjątkami i dobrze jest wiedzieć jak zaradzić zaśmiecaniu pamięci w pętli try..catch.

Najpierw mówiłeś coś innego, teraz mówisz coś innego, więc grzecznie przyznaj się do błędu zamiast teraz udawać eksperta w tym temacie.
Go to the top of the page
+Quote Post
vokiel
post 10.02.2018, 13:56:35
Post #46





Grupa: Zarejestrowani
Postów: 2 592
Pomógł: 445
Dołączył: 12.03.2007

Ostrzeżenie: (0%)
-----


Cytat(SmokAnalog @ 9.02.2018, 23:52:51 ) *
Darko, nie oUbolewam nad tym, że przez całą noc crawluję zaledwie 20-30 tys. wyników,


Jeśli to za mało to mam kilka propozycji
* cURL zamiast file_get_contnets (w wielu wypadkach cURL jest szybsze, więcej rzeczy można ustawić)
* curl_multi - aby zwielokrotnić ilość pobieranych zasobów
* kilka procesów na raz

Prosty przykład:
  1. <?php
  2.  
  3. for($i = 259010; $i<259310; $i++){
  4. $url = 'http://forum.php.pl/index.php?showtopic=' . $i;
  5. $html = file_get_contents($url);
  6. $usage = memory_get_usage();
  7. $usageTrue = memory_get_usage(true);
  8. echo date('H:i:s').'.'.gettimeofday()['usec'].' | ID: '.$i.' length: '.strlen($html).' | usage: '.$usage.' | usage(true) '.$usageTrue.PHP_EOL;
  9. }


Test (obcięte wyniki do dwóch pierwszych i ostatnich)

  1. $ time php file_get_contents.php
  2.  
  3. 13:48:46.202671 | ID: 259010 length: 221566 | usage: 592840 | usage(true) 2097152
  4. 13:48:46.291102 | ID: 259011 length: 40984 | usage: 414280 | usage(true) 2097152
  5. ..
  6. 13:49:54.433896 | ID: 259308 length: 38852 | usage: 410184 | usage(true) 2097152
  7. 13:49:54.573305 | ID: 259309 length: 76766 | usage: 447048 | usage(true) 2097152
  8.  
  9. real 1m8.822s
  10. user 0m0.193s
  11. sys 0m0.284s


Wersja na curl:
  1. <?php
  2.  
  3. for($i = 259010; $i<259310; $i++){
  4. $url = 'http://forum.php.pl/index.php?showtopic=' . $i;
  5.  
  6. $ch = curl_init();
  7. curl_setopt($ch, CURLOPT_URL, $url);
  8. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  9. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
  10. curl_setopt($ch, CURLOPT_HEADER, 0);
  11. $html = curl_exec($ch);
  12. curl_close($ch);
  13.  
  14. $usage = memory_get_usage();
  15. $usageTrue = memory_get_usage(true);
  16. echo date('H:i:s').'.'.gettimeofday()['usec'].' | ID: '.$i.' length: '.strlen($html).' | usage: '.$usage.' | usage(true) '.$usageTrue.PHP_EOL;
  17. }
  18.  


  1. $ time php curl.php
  2.  
  3. 13:50:54.645658 | ID: 259010 length: 221568 | usage: 594096 | usage(true) 2097152
  4. 13:50:54.875325 | ID: 259011 length: 40984 | usage: 415536 | usage(true) 2097152
  5.  
  6. 13:51:41.684053 | ID: 259308 length: 38852 | usage: 411440 | usage(true) 2097152
  7. 13:51:41.888811 | ID: 259309 length: 76766 | usage: 448304 | usage(true) 2097152
  8.  
  9. real 0m48.066s
  10. user 0m0.227s
  11. sys 0m0.270s


A bez curl_setopt($ch, CURLOPT_HEADER, 0); trwało porównywalnie do wersji z file_get_contents:
  1. real 0m56.110s
  2. user 0m0.176s
  3. sys 0m0.185s


Wersja z curl_multi
  1. <?php
  2.  
  3. $urls = [];
  4. for($i = 259010; $i<259310; $i++){
  5. $urls[] = $i;
  6. }
  7.  
  8. $ch_multi = curl_multi_init();
  9. $ch_arrr = [];
  10.  
  11. $options = [
  12. CURLOPT_RETURNTRANSFER => true,
  13. CURLOPT_FOLLOWLOCATION => true,
  14. CURLOPT_MAXREDIRS => 3,
  15. CURLOPT_HEADER => 0,
  16. CURLOPT_CONNECTTIMEOUT => 3,
  17. ];
  18.  
  19. for ($i = 0; $i < 2; $i++){
  20. $ch = curl_init();
  21. $options[CURLOPT_URL] = 'http://forum.php.pl/index.php?showtopic='.$urls[$i];
  22. curl_setopt_array($ch, $options);
  23. curl_multi_add_handle($ch_multi, $ch);
  24. }
  25.  
  26. do {
  27. while (($execrun = curl_multi_exec($ch_multi, $running)) == CURLM_CALL_MULTI_PERFORM);
  28. if($execrun != CURLM_OK){
  29. break;
  30. }
  31.  
  32. while ($done = curl_multi_info_read($ch_multi)) {
  33. $html = curl_multi_getcontent($done['handle']);
  34.  
  35. $usage = memory_get_usage();
  36. $usageTrue = memory_get_usage(true);
  37. echo date('H:i:s').'.'.gettimeofday()['usec'].' | ID: '.$urls[$i].' length: '.strlen($html).' | usage: '.$usage.' | usage(true) '.$usageTrue.PHP_EOL;
  38.  
  39. ++$i;
  40. if (!empty($urls[$i])) {
  41. $ch = curl_init();
  42. $options[CURLOPT_URL] = 'http://forum.php.pl/index.php?showtopic='.$urls[$i];
  43. curl_setopt_array($ch, $options);
  44. curl_multi_add_handle($ch_multi, $ch);
  45. }
  46. curl_multi_remove_handle($ch_multi, $done['handle']);
  47. }
  48. } while ($running);
  49.  
  50. curl_multi_close($ch_multi);


  1. $ time php curl_multi.php
  2. 13:55:01.296270 | ID: 259011 length: 40987 | usage: 442440 | usage(true) 2097152
  3. 13:55:01.425666 | ID: 259012 length: 41189 | usage: 444104 | usage(true) 2097152
  4.  
  5. 13:55:33.281197 | ID: 259308 length: 76766 | usage: 518152 | usage(true) 2097152
  6. 13:55:33.370113 | ID: 259309 length: 38852 | usage: 518112 | usage(true) 2097152
  7.  
  8. real 0m32.255s
  9. user 0m20.641s
  10. sys 0m11.609s


Podsumowanie
* file_get_contents: 1m8.822s
* curl: 0m48.066s
* curl_multi: 0m32.255s

Ten post edytował vokiel 10.02.2018, 13:59:38


--------------------
Go to the top of the page
+Quote Post
darko
post 10.02.2018, 14:06:37
Post #47





Grupa: Zarejestrowani
Postów: 2 885
Pomógł: 463
Dołączył: 3.10.2009
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


Cytat(SmokAnalog @ 10.02.2018, 03:52:36 ) *
Jeszcze przed chwilą mówiłeś, że PHP się nie nadaje do daemonów i crawlerów, co jest kompletną bzdurą.
Najpierw mówiłeś coś innego, teraz mówisz coś innego, więc grzecznie przyznaj się do błędu zamiast teraz udawać eksperta w tym temacie.

Błędu? Jakiego błędu? Ja podtrzymuję to, co napisałem. Do napisania wydajnego crawlera ludzie wybierają inne niż php narzędzia: perl, python, javę, a nawet basha czy node.js. Rozumiem, że Ty jesteś z tych, co uważają, że programowanie zaczyna się w momencie napisania pierwszej linii kodu. Dla mnie programowanie to najpierw dogłębna analiza problemu i dobranie optymalnego (czyt. najlepszego) narzędzia do danej sytuacji, a nie pisanie w tym, w czym wydaje Ci się, że umiesz to zrobić i jakoś to będzie. Jak widać, jakoś to nie będzie. Jakoś to nie jakość, a forum jest od rozwiązywania problemów, a nie od ich mnożenia. Vokiel już Ci podał na tacy kilka możliwych rozwiązań, ale pewnie i tak będziesz się upierał przy swoim, że po co, że na co tak itd. Kończę tę jałową przepychankę, bo pojawiają się z Twojej strony argumenty z półki ad personam, co nigdy dla poważnej rozmowy niczego dobrego nie wróżyło. Ponownie pozdrawiam Cię i mimo wszystko życzę Ci powodzenia i owocnej nauki. Miłego dnia.


--------------------
Nie pomagam na pw, tylko forum.
Go to the top of the page
+Quote Post
phpion
post 11.02.2018, 19:35:00
Post #48





Grupa: Moderatorzy
Postów: 6 070
Pomógł: 860
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Panowie, nie ma się co tak napinać. Każdy z Was wnosi konkrety do dyskusji nawet jeśli zdania są podzielone. Sam z ciekawością czytam wypowiedzi jednego i drugiego. Można się spierać ale trzymajmy poziom, osobiste wycieczki są daremne. Nie jesteście zapewne nastolatkami więc powinniście podejść do dyskusji na odpowiednim poziomie. Każda wypowiedź jest cenna i tego się trzymajmy. Żaden z Was chyba nie pisze po to żeby dogryźć drugiemu. Nie ma co być uszczypliwymi.
Go to the top of the page
+Quote Post

3 Stron V  < 1 2 3
Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 25.04.2024 - 09:28