Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Pamięc serwera a wgrywanie plików
Forum PHP.pl > Forum > PHP
johnyMajster
Witam
Zrobiłem sobie upload plków i mam pewien problem otóż przy ładowaniu obrazka o rozmiarze 8 megabajtów otrzymuję taki oto bład
Allowed memory size of 134217728 bytes exhausted (tried to allocate 6293 bytes)

Z tego co przeczytałem oznacza on że serwer potrzebuje wiecej pamieci niz mu przydzieliłem i nawet wiem jak ją zwiekszyc.

Pojawia sie jednak pytanie czy to normalne ze przy przetwarzaniu obrazka 8megabajtów serwer potrzebuje az tyle pamieci?? To co sie stanie jak będę miał serwer z 8GB ramu i milion wgrywanych plików przez różnych użytkowników sad.gif questionmark.gifquestionmark.gif
szalek01
istotna jest też rozdzielczość obrazka, co robisz gdy go wysyłasz na serwer ? generujesz miniaturki czy coś ?
spokoloko123
Cytat(szalek01 @ 30.09.2012, 00:28:31 ) *
istotna jest też rozdzielczość obrazka, co robisz gdy go wysyłasz na serwer ? generujesz miniaturki czy coś ?

Nawet jak byś generował miniatury to nie powinno być problemu(134217728B = 128MB to wystarczająco), możliwe, że gdzieś wycieka ci pamięć. Przejrzyj skrypt ew. spróbuj dodać na początku to:
  1. ini_set('memory_limit', '-1');

Lecz przy takim limicie stawiam na:
1. Udało ci się napisać super niewydajny skrypt
2. Gdzieś coś ci wycieka "memory leaking", przeglądnij dodatkowo poprawność pętli.
johnyMajster
Cytat(szalek01 @ 30.09.2012, 00:28:31 ) *
istotna jest też rozdzielczość obrazka, co robisz gdy go wysyłasz na serwer ? generujesz miniaturki czy coś ?


Wgrywam obrazek 6700X4700

Robie trzy mniejsze na podstawie tego wiekszego

800X600
400X300
150X100

Dodatkowo sprawdzam czy użytkownik jest włascicielem konta


Cytat(spokoloko123 @ 30.09.2012, 17:22:56 ) *
Nawet jak byś generował miniatury to nie powinno być problemu(134217728B = 128MB to wystarczająco), możliwe, że gdzieś wycieka ci pamięć. Przejrzyj skrypt ew. spróbuj dodać na początku to:
  1. ini_set('memory_limit', '-1');

Lecz przy takim limicie stawiam na:
1. Udało ci się napisać super niewydajny skrypt
2. Gdzieś coś ci wycieka "memory leaking", przeglądnij dodatkowo poprawność pętli.

Rzeczywiscie jak to dałem to śmiga na 128. Ile mniej wiecej mega powinien wymagac skrypt do uploadu?
Crozin
Problemem nie jest wgrywanie pliku, a jego wczytanie przez skrypt generujący miniatury, ponieważ ten ostatni wymaga całego obrazu w pamięci. Obraz o rozdzielczości 6700×4700 to 90 do 120 MiB danych (w zależności od obecności kanału alpha w obrazie).

Jeżeli mamy problem z pojemnością jakieś zmiennej/dysku/czegokolwiek powinniśmy dążyć do zwiększenia jej nie dwukrotnie, a o rząd wielkości. Tutaj byłoby to więc 1024 MiB, jednak 512 MiB myślę, że również wystarczy.
johnyMajster
Cytat(Crozin @ 30.09.2012, 19:54:21 ) *
Problemem nie jest wgrywanie pliku, a jego wczytanie przez skrypt generujący miniatury, ponieważ ten ostatni wymaga całego obrazu w pamięci. Obraz o rozdzielczości 6700×4700 to 90 do 120 MiB danych (w zależności od obecności kanału alpha w obrazie).

Jeżeli mamy problem z pojemnością jakieś zmiennej/dysku/czegokolwiek powinniśmy dążyć do zwiększenia jej nie dwukrotnie, a o rząd wielkości. Tutaj byłoby to więc 1024 MiB, jednak 512 MiB myślę, że również wystarczy.


Sprawdziłem błąd generuje linijka z ImageCreateFromJPEG.
Zastanawia mnie jak pisac optymalne skrypty moze cos podpowiecie smile.gif
korzystam ze skryptu z gajdy:

  1. <?php
  2.  
  3. class My_Thumbnail
  4. {
  5.  
  6. /*
  7.   * Jeśli obraz jest poziomy to jest skalowany do szerokości AWidth
  8.   * Jeśli obraz jest pionowy to jest skalowany do wysokości AHeight
  9.   * Kwadratowy: skalujemy do wysokości AHeight
  10.   *
  11.   * Parametr $AImg jest obiektem GD
  12.   * Wynik - miniaturka - jest zwracany jako obiekt GD
  13.   */
  14. public static function gdThumbnailObj($AImg, $AWidth, $AHeight)
  15. {
  16. if (!$AImg) {
  17. die('gd_thumbnail_obj() - $AImg error');
  18. }
  19.  
  20. $AImg_X = ImageSX($AImg);
  21. $AImg_Y = ImageSY($AImg);
  22.  
  23. $tmp_Y = ($AWidth / $AImg_X) * $AImg_Y;
  24. $tmp_X = ($AHeight / $AImg_Y) * $AImg_X;
  25.  
  26. if ($tmp_Y <= $AHeight){
  27. $thumbnail_X = $AWidth;
  28. $thumbnail_Y = $tmp_Y;
  29. } else {
  30. $thumbnail_X = $tmp_X;
  31. $thumbnail_Y = $AHeight;
  32. }
  33.  
  34. $thumbnail = ImageCreateTrueColor(
  35. $thumbnail_X,
  36. $thumbnail_Y
  37. );
  38.  
  39. imageAlphaBlending($thumbnail, false);
  40. imageSaveAlpha($thumbnail, true);
  41.  
  42. ImageCopyResized(
  43. $thumbnail, $AImg, //przeznaczenie, zrodlo
  44. 0, 0, //gdzie ma trafic w przeznaczeniu
  45. 0, 0, //skad ma pochodzic ze zrodla
  46. $thumbnail_X, $thumbnail_Y, //wymiary, jakie ma zająć w przeznaczeniu
  47. $AImg_X, $AImg_Y //wymiary pobierane ze źródła
  48. );
  49. return $thumbnail;
  50. }
  51.  
  52.  
  53. /*
  54.   * Funkcja identyczna jak function gd_thumbnail_obj()
  55.   * Różni się parametrami.
  56.   *
  57.   * Pierwszy parametr - $AFileName - to nazwa pliku do przeskalowania
  58.   * Wynik - miniaturka - jest zwracany jako obiekt GD
  59.   */
  60. public static function gdThumbnailFile($AFileName, $AWidth, $AHeight, $destFilename, $quality = 95)
  61. {
  62. $img = ImageCreateFromJPEG($AFileName);
  63. $mini = self::gdThumbnailObj($img, $AWidth, $AHeight);
  64. imagejpeg($mini, $destFilename, $quality);
  65. }
  66.  
  67. }

Crozin
Problemem jest konieczność wczytania całego obrazu na raz do pamięci przy korzystaniu z GD. Ty natomiast musiałbyś albo zwiększyć limit pamięci, albo wykonywać miniaturki fragmentów obrazu. To ostatnie na pewno pozwoliłoby na małe zużycie pamięci, ale będzie wolniejsze i dużo, dużo bardziej skomplikowane - prawdopodobnie nie istnieją nawet gotowe narzędzia do realizacji tego w PHP.

Cytat
Zastanawia mnie jak pisac optymalne skrypty moze cos podpowiecie
Ale optymalnie względem czego? Zużycia pamięci, pracy dysku, czasu pracy procesora itp. itd. Nie zawsze da się zrobić coś "naj" we wszystkich kategoriach.
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.