ugrás a tartalomhoz

Elfogy a memória PHP alól

gabesz666 · 2012. Aug. 21. (K), 10.34
Sziasztok!

A segítségemet kérték egy oldalnál, ahol a galéria furcsa módon néha megjeleníti az összes képet, néha meg kihagy párat. A rendszergazda szerint az a gond, hogy elfogy a memória a PHP alól, de én ebben nem vagyok 100%-ig biztos, mondom is miért. Eddig phpThumb gyártotta le a galéria képek kis méretű változatát, de mivel ennek a kódját nem ismerem annyira, írtam egy nagyon egyszerű, saját átméretező scriptet, ami ha nem létezik megadott méretű kis kép, legenerálja azt, ellenkező esetben csak beolvassa a fájlt, majd kitolja az outputra. Ami egészen biztos, hogy most már az összes képnek legenerálta a kis méretű változatát, így azokat csak be kell olvasni, mégis van olyan, hogy egy 5 képes (maximum képméret 30 Kb) album esetén 2-3 képnél is meghal a script. Szerintetek ez lehetséges, hogy ennyitől elfogyna a memória? Azt nem értem, ha elfogy a maradék process miért nem várakozik kicsit, amíg felszabadul elég memória a futáshoz, ahelyett hogy egyből elszáll 500-as erroral.

(ha jól tudom 256 mb memóriával fut a vps)
 
1

FirePHP

Hidvégi Gábor · 2012. Aug. 21. (K), 12.11
Ha még nem használod, érdemes Firefox alá feltenni a FirePHP-t, azzal könnyen ki tudod íratni konzolra a php-s hibaüzeneteket, azaz látni fogod a képeknél, mi a baj (ha tényleg elfogy a memória, akkor a kép újbóli betöltésénél nem lesz hiba ugye).
2

Ha a HTML oldalt generáló

tgr · 2012. Aug. 21. (K), 13.20
Ha a HTML oldalt generáló processznek fogy el a memóriája, az fatal error, és a FirePHP nem tud küldeni semmit. Ha egy háttérprocessznek, akkor meg azért nem tud küldeni semmit. Úgyhogy éppen semmi értelme ebben a szituációban (általában egyébként nagyon hasznos eszköz). Használd a hibalogot inkább.
3

Igaz

Hidvégi Gábor · 2012. Aug. 21. (K), 13.34
A Net panelen viszont meg lehet nézni, hogy a válaszban mi van.
4

Meg simán a böngszőablakban

tgr · 2012. Aug. 21. (K), 13.38
Meg simán a böngszőablakban is meg lehet nézni. De fatal error esetén nincs válasz, csak egy üres 500-as oldal (feltéve, hogy a hibaüzenetek HTML-ben való kiiratása le van tiltva).
7

Nincs hibaüzenet

gabesz666 · 2012. Aug. 21. (K), 14.00
A probléma az, hogy nincs sehol sem hibaüzenet. Error logban sem.
13

Ha kézzel generálsz egy fatal

tgr · 2012. Aug. 21. (K), 15.03
Ha kézzel generálsz egy fatal errort (pl. nincs_ilyen_fuggveny()), akkor van? CLI-ből is?
15

Igen, van

gabesz666 · 2012. Aug. 21. (K), 15.13
Igen, akkor van hibaüzenet. CLI-ből nem tudom ellenőrizni, mivel a vps-hez nem kaptam hozzáférést (ha jól tudom az oldal tulajának sincs).
22

Apache hibalog (meghaló child

tgr · 2012. Aug. 21. (K), 20.14
Apache hibalog (meghaló child processzek vagy ilyesmi)?
32

Illetve ha az OOM killer öli

tgr · 2012. Aug. 21. (K), 21.30
Illetve ha az OOM killer öli meg, akkor gondolom a syslog.
33

Ha van!

janoszen · 2012. Aug. 21. (K), 21.44
Ha van! Ez eleg minimalis VPS-nek nez ki, nem biztos, hogy raktak bele syslogot. A gazdagep Syslogjaban meg vagy benne van, vagy nincs, attol fugg, milyen virtualizaciot hasznalnak.
5

Azt nem értem, ha elfogy a

tgr · 2012. Aug. 21. (K), 13.38
Azt nem értem, ha elfogy a maradék process miért nem várakozik kicsit, amíg felszabadul elég memória a futáshoz, ahelyett hogy egyből elszáll 500-as erroral.

Mert amíg várakozik, foglalja a memóriát -> deadlock.
9

Nem értem

gabesz666 · 2012. Aug. 21. (K), 14.09
Nem egészen értem. Ha elindul mondjuk párhuzamosan 2 script futás és tegyük fel elfogyasztják az összes memóriát, akkor hogyan tudna a maradék 3 script memóriát foglalni magának?
12

Sehogy, ezért kellemetlen, ha

tgr · 2012. Aug. 21. (K), 14.58
Sehogy, ezért kellemetlen, ha ilyenkor az a két script nem hal meg, hanem várakozik.
14

Leírom egyértelműbben

gabesz666 · 2012. Aug. 21. (K), 15.11
Leírom egyértelműbben, hátha rosszul fogalmaztam. Tehát van egy 5 darab képből álló galéria. Betöltöm az oldalt. Ekkor meghívja párhuzamosan egyszerre az 5 képre a generáló scriptet. Ekkor tegyük fel az első 2 kép generálásánál elfogy a memória, így a maradék 3 scriptnek várakoznia kéne, amíg lefut az első 2 script és felszabadul elegendő memória. Viszont úgy tűnik, hogy a maradék 3 script kapásból elszáll 500-as erroral (elfogy a memória?) és nem várakozik semmire.
23

Ha a "kéne" alatt azt érted,

tgr · 2012. Aug. 21. (K), 20.14
Ha a "kéne" alatt azt érted, hogy szerinted így viselkedik a PHP, akkor nem, ha a szkript memóriát próbál allokálni és nem sikerül neki, akkor dob egy fatal errort és felszámolja magát.

Ha azt érted alatta, hogy nem így viselkedik, de szerinted így okosabb lenne, akkor meg azért nem, mert így amikor az első két szkript megette az összes szabad memóriát, akkor elkezdenének egymásra várni, hogy mikor fejeződnek be, te meg kelhetnél fel az éjszaka közepén újraindítani a webszervert, mert magától ebből nem mászna ki (vö. deadlock).
25

Memoria

janoszen · 2012. Aug. 21. (K), 20.17
Nem, ha elfogy a rendszermemoria, akkor Linux rendszereken az OOM killer fogja kiolni es nincs belole fatal error, mert odaig mar nem jut le a processz. Ergo ha mod_php-val fut, akkor a komplett Apache processz hal meg es a kliens meg kap egy "Connection reset" hibat.

Egyebkent elnezest, de kepeket barmilyen szinten beolvasni oldal rendereles kozben a vilag legnagyobb baromsaga, mert a PHP kepkezelo rutinjai borzaszto modon memoriaigenyesek es ami meg fontosabb, nem mindig veszik figyelembe a memory_limitet. A PHP ugyanis ket parancs vegrehajtas kozott ellenorzi az elfoglalt memoriat, az extensionok fuggvenyeinek futassa kozben viszont nem. Ergo a kepkezelo rutin siman tullepheti a memory_limitet, ha szarul van megirva.
27

Nem vitatva, hogy rossz

tgr · 2012. Aug. 21. (K), 20.25
Nem vitatva, hogy rossz ötlet, azért nem nehéz olyan szkriptet írni, ami konstans memóriaigénnyel olvas be és ír ki egy képfájlt.
28

Nyilvan

janoszen · 2012. Aug. 21. (K), 20.28
Nyilvan nem, de ha 256 MB-be bele kell fernie a scriptnek es az oldalkiszolgalasnak is figyelembe veve a parhuzamos lekereseket konnyen ki lehet szaladni a RAM-bol. *sohaj* de jo, hogy sajat szerverem van.
6

Alapvetően rossz ötlet a

tgr · 2012. Aug. 21. (K), 13.41
Alapvetően rossz ötlet a PHP-n át utaztatni a képeidet (nem annyira a memóriaigény miatt, hanem mert sokkal kevésbé hatékony, mint ha a webszerver szolgálná ki - nem fogod normálisan beállítani a fejléceket, és még ha véletlenül mégis megtennéd, akkor sem tudod kihasználni a webszerver cache-elését), de önmagában ettől nem kéne lehalnia az oldalnak. Valószínűleg hibás a szkripted, látatlanban nehéz megmondani.
8

Melyik része?

gabesz666 · 2012. Aug. 21. (K), 14.07
Alapvetően rossz ötlet a PHP-n át utaztatni a képeidet

Tisztában vagyok vele, de így kell megoldanom a feladatot!

Valószínűleg hibás a szkripted, látatlanban nehéz megmondani.

Melyik része hibás? Az hogy beolvasok egy fájlt és kiiratom? :) Egyébként nem titkos a kód, úgyhogy: képkezelő class és a generáló script.
10

Én két centem

dropout · 2012. Aug. 21. (K), 14.28
Rossz az egész logika.
Én legelőször azt nézném meg, hogy van-e thumbnail az adott file-ból mielőtt még ImageMagick objektumokat generálnék.
Aztán az ilyen képméretek lekérdezéséhez sincs szükség ImageMagick-ra. getimagesize()
Mondanom se kellene, de azért mégis: a bemenetet nem használnám ilyen nyersen.
Aztán, ha ez valami képgaléria lenne, érdemes inkább rendszerbe foglalni, mert így ez nagyon bindzsi. Gondolom valaki html-be pötyögi a képek url-jét, ha pedig nem, mert valahonnan kapja akkor ott érdemesebb lenne optimalizálni az egész folyamatot.
11

Az ImageMagick...

gabesz666 · 2012. Aug. 21. (K), 14.51
Én legelőször azt nézném meg, hogy van-e thumbnail az adott file-ból mielőtt még ImageMagick objektumokat generálnék.

Az ImageMagick objektum egészen pontosan 1296 byte memóriát eszik, az azért nem olyan vészes

Aztán az ilyen képméretek lekérdezéséhez sincs szükség ImageMagick-ra. getimagesize()

Mivel a használt class ImageMagick-re épül és az előbb említett egészen bődületes méretű memóriát megeszi, ezért gondoltam, hogy az egységesség jegyében használom erre is a már legyártott objektum metódusát.

Mondanom se kellene, de azért mégis: a bemenetet nem használnám ilyen nyersen.

Mondj egy példát kérlek, amikor az input problémát okoz!

Gondolom valaki html-be pötyögi a képek url-jét, ha pedig nem, mert valahonnan kapja akkor ott érdemesebb lenne optimalizálni az egész folyamatot.

A kód még közel sem production ready, egyrészt. Másrészt engem az érdekelne, hogy miért száll el a script, alternatív megoldásom van nekem is :)
16

Awwww....

dropout · 2012. Aug. 21. (K), 15.55
Az ImageMagick objektum egészen pontosan 1296 byte memóriát eszik, az azért nem olyan vészes


Minden egyes képet beolvas, ergo pixelenként tárolja a memóriában. Nem 30kbyte-al meg 1296byte -nak a többszörösével kell számolnod, hanem sokkal többel.

Mivel a használt class ImageMagick-re épül és az előbb említett egészen bődületes méretű memóriát megeszi, ezért gondoltam, hogy az egységesség jegyében használom erre is a már legyártott objektum metódusát.


Rossz a következtetés az elözőből kifolyólag, a többit már tudod.

Mondj egy példát kérlek, amikor az input problémát okoz!


Állásinterjún majd ne ezt válaszold, ha felvetik problémaként.

A kód még közel sem production ready, egyrészt. Másrészt engem az érdekelne, hogy miért száll el a script, alternatív megoldásom van nekem is :)


A rendszergazda megmondta, a script-edból látszik. Nem tudom mi kell még. Nyilván a pontos leállás okát nem a forrásból fogjuk megmondani... Ha logjaid nincsenek akkor már próbálgathatod is az alternatív megoldásaidat.
17

Re

gabesz666 · 2012. Aug. 21. (K), 16.49
Minden egyes képet beolvas, ergo pixelenként tárolja a memóriában. Nem 30kbyte-al meg 1296byte -nak a többszörösével kell számolnod, hanem sokkal többel.

Tévedsz! Az objektum inicializálás önmagában nem foglalja le a kép teljes (vagy raw) méretét a memóriában. De ha nem hiszed el végezz el egy tesztet!

Állásinterjún majd ne ezt válaszold, ha felvetik problémaként.

Ez nem válasz a kérdésre, hanem terelés. Egyébként ismerem a filter_var és filter_var_array függvényeket (és az egyéb filterezési és validálási best practice-eket), és szoktam is használni őket. Szóval mondasz egy olyan input halmazt, amivel a rendszer "törhető" lesz?

A rendszergazda megmondta, a script-edból látszik. Nem tudom mi kell még. Nyilván a pontos leállás okát nem a forrásból fogjuk megmondani... Ha logjaid nincsenek akkor már próbálgathatod is az alternatív megoldásaidat.

Igen, a rendszergazda megmondta, csak nekem szöget ütött a fejembe, hogy 2-3 30 Kb-os kép beolvasása és kiiratására hatására hogy a fenébe fogyhat el a memória :)
19

Az ember csak segíteni próbál, de azt is nehezen hiszik el

dropout · 2012. Aug. 21. (K), 17.46
1. De te nem csak inicializálsz egyrészt, másrészt az egységesség jegyében teljesen pazarlóan bánsz az erőforrásokkal. A kódod, logikád egy SZAR.
Még ha nem is a memória miatt van akkor is bemutatsz egy csomó felesleges komplickációt egy külső php modul meghívásával, lehet, hogy attól szarik be a rendszer, mert szarul van vmi konfigurálva. Én se írtam, hogy memória, csak gondolom, mert elég valószínű. Vettem a fáradtságot, megnéztem, és ezt láttam benne, de nem muszáj elhinni.

2. Leszarom ezt a szánalmas okfejtésedet a terelésről. Ebbe a rossz szokásba ahányszor látom annyiszor fogok belerúgni. Nem törhetőségről van szó, szerinted ezen mi a faszt törnek fel? Megbízható kódról van szó, érted? Ahol inputokat nem hagynak nyersen, nem csak azért, hogy ne lehessen injektálni, hanem azért mert szűkited a hiba lehetőségét. Gondolom, hogy nem a NASA-nak írsz gépgalériát, de azért bocs, hogy megjegyeztem.
Annyira vicces, hogy ír az ember egy tőmondatot és már a kis elméjével az olvasó hozzágondol 234234978234897 prekoncepciót, aztán magyarázkodhatsz sorokon keresztül.

3. Sok sikert kívánok akkor.
20

Köszi!

gabesz666 · 2012. Aug. 21. (K), 18.03
3. Sok sikert kívánok akkor.

Köszönöm, és az észrevételeket is!
18

Olyannyira...

gabesz666 · 2012. Aug. 21. (K), 17.20
Olyannyira szöget ütött a fejembe a probléma, hogy most felállítottam egy vm-et 256 mb memóriával, imagemagick-kel, php-val, hogy leteszteljem tényleg a szkriptem-e a ludas. 180 db 300-2000 Kb-os képet engedtem rá a scriptre (egyszerre) és 5 futás alatt egyetlen egy képnél sem szállt el memória limit miatt.
21

Memoria limit

janoszen · 2012. Aug. 21. (K), 19.51
Kerdes: memoria limit problema van, vagy a fizikai RAM fogy el? Egyebkent ha 64 MB RAM-nal tobbet eszik a PHP, akkor ott mar valami nem OK, foleg ha sokan utik egyszerre a szervert.

Esetleg postolj mar egy phpinfo kimenetet.
24

PhpInfo

gabesz666 · 2012. Aug. 21. (K), 20.16
A memória limit 256 mb, de ennyi a fizikai memória is a gépben. Egyébként ez egy nagyon pici oldal, mellette ugyan fut még pár kisebb oldal a gépen, de összességében nincs nagy terhelése a vm-nek. Mire tippelsz? Mi más lehet még a baja? Én teljesen kifogytam az ötletekből. Ha legalább lenne egy strace-em, de sajnos az most nem opció. :S
A phpinfo kimenet: http://szabogabor.net/blog_files/phpinfo.html.
26

Parhuzamos

janoszen · 2012. Aug. 21. (K), 20.21
A modern bongeszok parhuzamosan 6 szalon toltik a tartalmakat, ergo 6 kep fog egyszerre betoltodni (hacsak nincs korlatozva a parhuzamos PHP instanceokszama), raadasul az oprendszernek is kell memoria. Ennek kovetkezteben a programodnak legoptimalisabb esetben is 40 MB memoriaba kellene belefernie, hogy ne kezdjen el dolgozni az OOM killer. (Nekem meg nem sikerult PHP-s virtualis gepet osszehozni 10 MB RAM fogyasztas alatt., innen a durvan 40 MB.)

Egyebkent milyen okbol kifolyolag van RAM-korlatos virtualis gepben a PHP? Tarhelyeknel szokas burstolni hagyni az ugyfelet.

Tipp: ha gyors megoldast akarsz, csinalj egy flock() hivast egy filera es akkor egyszerre csak egy kep dolgozodik fel, a tobbi var.
34

Egyebkent milyen okbol

gabesz666 · 2012. Aug. 21. (K), 22.21
Egyebkent milyen okbol kifolyolag van RAM-korlatos virtualis gepben a PHP? Tarhelyeknel szokas burstolni hagyni az ugyfelet.

Azt nem tudom, csak azt, hogy erről a szolgáltatásról van szó: Cloud 20 csomag

Tipp: ha gyors megoldast akarsz, csinalj egy flock() hivast egy filera es akkor egyszerre csak egy kep dolgozodik fel, a tobbi var.

Köszi, mindenképp azt szeretném megoldásképpen, amit tgr is javasolt, hogy webszerverről szolgálom ki a képet (mármint a php kihagyásával ha lehetséges, ha pedig nincs még generálva, akkor php-ból meggenerálom). Ez volt az eredeti terv is. Alapvetően engem az érdekelne, hogy mi okozza a problémát, mert ilyet még nem láttam.
29

Mondj egy példát kérlek,

tgr · 2012. Aug. 21. (K), 20.31
Mondj egy példát kérlek, amikor az input problémát okoz!


allow_url_fopen=1 mellett tetszőleges forrásfájlt meg lehet neki adni, valamelyik EXIM mezőbe, amit megőriz az imagemagick, PHP kódot írni, és meg is törték a webszerveredet.
31

Ebbe azért én is belegondoltam

gabesz666 · 2012. Aug. 21. (K), 20.56
Meglehetne törni, ha így lenne beállítva a szerver. De nem így van. Ez volt a legelső amit megnéztem a konfigban, mielőtt bepostoltam a kódot. :)
De mégegyszer elmondom: a kód nem production ready, lesz benne még ellenőrzés, csak tesztelésképpen írtam, hogy ugyanaz történik-e mint a phpThumbnail esetén.
30

Én legelőször azt nézném meg,

tgr · 2012. Aug. 21. (K), 20.42
Én legelőször azt nézném meg, hogy van-e thumbnail az adott file-ból mielőtt még ImageMagick objektumokat generálnék.


A normális megoldás az, hogy GET paraméterek helyett a tényleges thumbnail fájlneveket teszed a HTML fájlba, és 404 handlerrel vagy rewrite rule-lal átküldöd a PHP-nek azokat a képletöltéseket, amiknél hiányzik a fájl. (És ha nagy forgalmú a site, akkor teszel bele valami cache stampede védelmet, de nyilván ha nagy forgalmú lenne, akkor nem egy 256 megás virtuális gépről futna.)
41

Igen így még jobb

dropout · 2012. Aug. 23. (Cs), 09.32
Igen így még jobb... de hát hiába a sok javaslat, látod mindenre van válasz, hogy miért kell szarul megírt kóddal bindzsi megoldássokkal operálni, csak mi nem érthetjük.
35

Ha nem szabadítod fel a

inf · 2012. Aug. 21. (K), 23.15
Ha nem szabadítod fel a memóriát minden kép kicsinyítés során imagedestroy-al, akkor elég hamar el tud fogyni. Én sprite készítéssel jártam így. Ha már tényleg minden kis kép megvan, és nem olvasod be az összeset, csak a fájlneveket nézegeted, akkor nem szabadna, hogy elfogyjon. Ha meg elfogy a memória, akkor nem tesz ki semmit output-ra, amit addig nem echo-ztál ki... A kimaradásnál szerintem arra gondolt a rendszergazda, hogy a kép méretező scriptednél fogy el a memória, és ezért elszáll, és nem készül kiskép minden nagy képről. Gondolom úgy gondolta, hogy külön cron vagy valami hasonló futtatja, ami persze nem igaz a fentiek alapján.

A memória fogyást ki lehet íratni memory_get_usage-al, próbálkozz azzal a kód egyes részein, meg én a helyedben egy xdebuggal megprofiloznám, ha tényleg ilyen gond van, viszont szerintem csak szimplán valami hiba van a kódodban.

Most nézem, hogy a kódban, amit küldtél php-val szolgálod ki a képeket echo-val, ami szerintem elég pazarló. Egy fájlt simán ki tud küldeni a szerver is, ilyesmire csak akkor van szükség, ha védeni akarod a fájlokat valami miatt...
36

Nincs átméretezés minden képnél

gabesz666 · 2012. Aug. 22. (Sze), 14.02
Először is, köszönöm a válaszod!
Másodszor tisztáznám a helyzetet mégegyszer, mert úgy érzem meg kell védenem a mundér becsületét és mert a legtöbb embernek a téma elolvasása után annyi jött le, hogy itt egy balfék, aki php scripttel átméretez minden egyes oldalletöltésnél minden egyes képet. És ne érts félre inferno, ezt nem konkrétan Neked írom. Tehát:

1. Ahhoz, hogy kiderítsem a problémát, a phpThumb helyett kellett csinálnom egy olyan scriptet, ami kb. ugyanazt csinálja és átlátom. Ezt mindössze DEBUGGOLÁSI CÉLBÓL ÍRTAM.

Ami egészen biztos, hogy most már az összes képnek legenerálta a kis méretű változatát, így azokat csak be kell olvasni, mégis van olyan, hogy egy 5 képes (maximum képméret 30 Kb) album esetén 2-3 képnél is meghal a script.

2. Leírtam a témaindító hozzászólásban, hogy nem (csak) az átméretezés során fut hibára a script, hanem egy-egy igen kis méretű fájl beolvasása és kiiratása után is (és most fognak jönni azok a válaszok, hogy "deigenisvanimagemagickmertmegnézedaméretétis" és igen, igazad van, van, de a phpThumb viszont úgy emlékszem, hogy egyből cache-ből tolja a képet, méret ellenőrzés nélkül és az a script IS elszáll)

Szerintetek ez lehetséges, hogy ennyitől elfogyna a memória? Azt nem értem, ha elfogy a maradék process miért nem várakozik kicsit, amíg felszabadul elég memória a futáshoz, ahelyett hogy egyből elszáll 500-as erroral.

3. Az volt a kérdés, hogy lehetséges-e ekkora memória fogyasztás egy ilyen algoritmusnál. Nem az, hogy szar-e a kódom, hogy szar-e a logikám vagy hogy mit csinálnátok a raw inputtal. Ehhez képest totál nem erre kaptam választ. Elmondtam ezt is, de leírom mégegyszer: engem az érdekel, hogy miért fut 500-as hibára a script, mert ez akár a többi oldal esetén is okozhat problémát, más scriptek esetén.

És akkor most jöjjön az érdemi válasz része :)

Ha nem szabadítod fel a memóriát minden kép kicsinyítés során imagedestroy-al, akkor elég hamar el tud fogyni.

Az egy GD függvény, ha jól emlékszem, ImageMagick-nél elvileg a destruktor automatikusan felszabadítja a memóriát.
Ha már tényleg minden kis kép megvan, és nem olvasod be az összeset, csak a fájlneveket nézegeted, akkor nem szabadna, hogy elfogyjon.

30 Kb-os fájlok esetén meg kiváltképp nem. Főleg, hogy a saját gépemen futtatott VM-ben hasonló műveletnél a php beérte 25-30 Mb-al. (processenként)
A memória fogyást ki lehet íratni memory_get_usage-al, próbálkozz azzal a kód egyes részein, meg én a helyedben egy xdebuggal megprofiloznám, ha tényleg ilyen gond van, viszont szerintem csak szimplán valami hiba van a kódodban.

Én az exec("free", $meminfo) paranccsal próbálkoztam, hogy hitelesebb képet kapjak a memóriáról.
ilyesmire csak akkor van szükség, ha védeni akarod a fájlokat valami miatt...

Igen, ez volt a másik dolog, amit figyelembe sem vett senki, hogy akár lehet valami oka is annak, hogy így szolgálom ki a képeket. Nincs egyébként :) De lehetett volna!
37

Ha felszabadítja a scripted a

inf · 2012. Aug. 22. (Sze), 14.19
Ha felszabadítja a scripted a memóriát minden méretezés után, akkor nem fordulhat elő, hogy ennyitől elfogy. Nekem ritkán szokott gondom lenni még 128-al is... Persze előfordulhat, hogy valami memory leak-es php verziót és kódot használsz. Sajnos ez a nyelv nem a legkiforrottabb ilyen téren (más téren sem :d).
38

A baj

janoszen · 2012. Aug. 22. (Sze), 17.03
Gyerekek, az a baj, hogy az ÖSSZES PHP szálnak el kell férnie 256 MB RAM-ban, nem csak egynek! Ha minden képbetöltés PHP-n keresztül fut, akkor az 6 (!) szál böngészőnként, aminek el kell ennyiben férnie! Ráadásul a PHP tud memleakelni, ha olyan a kód.
39

Jó, hát én írtam, hogy ne

inf · 2012. Aug. 22. (Sze), 19.04
Jó, hát én írtam, hogy ne echo-za a képeket, hanem küldje ki apache-al. Ha le akarja védeni őket, akkor is le lehet htaccess-el, szóval még az sem érv emellett... Így, hogy 6 szálnak kellene elférnie benne már necces, de szerintem még úgy is illene beleférnie...
40

Az IE10 egyébként már 8

tgr · 2012. Aug. 22. (Sze), 19.23
Az IE10 egyébként már 8 szálon tölt.
42

Az előttem felszólalókkal

Kubi · 2012. Aug. 23. (Cs), 10.33
Az előttem felszólalókkal értek egyet, akik azt mondták, hibás a logikád.

Ha csak egy thumbnailt jelenítesz meg, minek imagemagick, vagy bármi más kép manipuláló akármi? Kitolod 2kb-onként fread echo párossal amig tart a fájl és kész. Megfelelően kialakított logikával még a fájl tipusát sem kell ellenörizned, kéri a fájlt ha van már tolod is, memoria használat pedig 1mb alatt marad.

A memória számolásba nem vettetek bele egy gyakori esetet, mi van ha 2 látogatód nézi az oldalt egyszerre, és nem 6, hanem 12 kép letöltés megy párhuzamossan? Vagy ha így még épp elférsz, mi van ha 3 látogatód van? Nagyon hamar eljutsz egy olyan látogató számhoz ahol a felvázolt megoldásod nem alkalmazható.

Fenti okok miatt is, az első kéréskor generált thumbnail is hanyagolnám, több vele a szívás mint a haszna, kép feltöltéskor generálj thumbnailt. Van egy nagyon jó library: wideimage, érdemes használni.
43

Lásd

gabesz666 · 2012. Aug. 23. (Cs), 10.37
44

Az én tapasztalataim:Az

Kubi · 2012. Aug. 23. (Cs), 12.23
Az én tapasztalataim:

Az imagick által használt memóriát a memory_get_peak_usage illetve a memory_get_usage
nem mutatja, php memory limit nincs rá hatással.

$image = new Imagick("teszt.jpg");

echo $image->getresource($image::RESOURCETYPE_MEMORY) / (1024*1024);

$image->resizeimage(200,200, imagick::FILTER_LANCZOS, 0.9, true);
$image->writeimage("teszt2.jpg");

echo '<br />';
echo memory_get_peak_usage(true) / (1024*1024);
Ha már csak példányosítod az Imagick-et, lefoglalja a memóriát. 200x200 px-es kép esetén ez nálam 0.22 MB, 1024x1024 esetén 14Mb

Ha nem csinálod a kép átméretezést, ugyanazt az eredményt kapot.

Virtuális gépen koznolban a "free" parancsal figyeltem a memória fogyasztást, fenti script cli-ben indítva kb a fentinek megfelelő mennyiségű memóriát evett (akkor beletettem egy sleep parancsot, hogy legyen időm meg nézni), kép átméretezés nélkül is próbáltam.
45

Riszpekt

dropout · 2012. Aug. 23. (Cs), 13.00
Jó, hogy vetted a fáradtságot és megnézted pontosan mi történik, talán így elhiszi amit már nemtudomhányszor elmondtunk.
Nyilván nem lehet megúszni a kép pixelenkénti tárolásának memóriaigényét még képméret lekérdezés esetén sem, maximum metadata-ból kiolvasva, de hát egy komoly képkezelő könyvtár esetében ez elég banális feltételezés lenne.
Ha már valaki írt mondjuk egy bmp file beolvasót valami normális programozási nyelven, egyértelmű lehet számára a következtetés, de teszt nélkül már nem akartam mégjobban belemélyedni, hogy mit jelent informatikában a képkezelés.
46

Fenti okok miatt is, az első

inf · 2012. Aug. 23. (Cs), 15.57
Fenti okok miatt is, az első kéréskor generált thumbnail is hanyagolnám, több vele a szívás mint a haszna, kép feltöltéskor generálj thumbnailt. Van egy nagyon jó library: wideimage, érdemes használni.

Fura, legközelebb rendesen végigolvasom, amit írt, nekem eszembe sem jutna nem kép feltöltéskor megcsinálni a thumbnail-eket, mert adatbázisba nem tudnám lementeni a nevüket...
48

Akkor nagyon rosszul teszem?

unregistered · 2012. Aug. 24. (P), 08.07
Olvasgatom ezt a témát, mert nagyon érdekes és tanulságos, de akkor most én nagyon rosszul csinálom (erőforrásügyileg) hogy egy galéria kis képeihez nem thumb-okoat használok hanem ezt a kódot? (az elejét nem teszem be mert az csak az értékek meghatározása, így lényegtelen a kérdés szempontjából)

// új, üres kép létrehozása az új méretekkel:
	$uj_kep = ImageCreateTrueColor($uj_szelesseg, $uj_magassag);
	
	// az eredeti kép lekicsinyítése:
	ImageCopyResampled($uj_kep, $kep, 0, 0, 0, 0, $uj_szelesseg, $uj_magassag, $szelesseg, $magassag);
	
	$src = $uj_kep;
	$dest = imagecreatetruecolor(75, 75);

	// crop
	imagecopy($dest, $src, 0, 0, $cropside, $croptop, 75, 75);
	
	// a lekicsinyített kép megjelenítése:
	header ("Content-type: image/jpeg");
	ImageJpeg($dest);
	
	// a memória felszabadítása:
	ImageDestroy($kep);
	ImageDestroy($uj_kep);
	ImageDestroy($src);
	ImageDestroy($dest);
Előre is köszönöm!
49

Az erőforrásigényes dolgokat

inf · 2012. Aug. 24. (P), 08.37
Az erőforrásigényes dolgokat általában kesselni szokták, a kép méretezés meg erőforrás igényes dolog.

Ha kicsi a látogató szám, és kiküldesz egy header-t, hogy cachelje a böngésző, akkor nem számít sokat. Ha nő a látogató szám, akkor viszont feleslegesen terheled vele a szervert... Az általánosan elfogadott megoldás (legalábbis szerintem), hogy a kép feltöltésekor generálod hozzá a thumbnail-t. A scripteden alapból lehetne javítani, ha nem a végén szabadítanád fel a memóriát, hanem minden olyan lépés után, amikor megszabadulsz valamelyik képtől. Mondjuk 4 képnél ez nem számít annyira, de egy nagyobb sprite készítésénél már simán lehet szűk keresztmetszet. A jogosultság kezelést RewriteMap-el meg lehet oldani, ha védett képekről van szó, nem kell ezért beolvasni minden egyes képet a memóriába. (Nem tudom, hogy az apache féle fájl küldés hogy zajlik, de gondolom hatékonyabban, mint a php féle beolvasás + echo.)
50

Szerintem is

Pepita · 2012. Aug. 28. (K), 00.53
Az általánosan elfogadott megoldás (legalábbis szerintem), hogy a kép feltöltésekor generálod hozzá a thumbnail-t.
Ez legalább az esetek 90%-ában így van, mondjuk adatbázist nem feltétlenül kell használni, sok esetben egyszerű könyvtárolvasással is legenerálható egy galéria képlistája. (Persze a legtöbb honlaphoz amúgy is kell db, akkor már jobb az a plusz 1-2 tábla...)
(Nem tudom, hogy az apache féle fájl küldés hogy zajlik, de gondolom hatékonyabban, mint a php féle beolvasás + echo.)
Ezt viszonylag könnyen lemérheted localhoston. A legtutibb az, ha a kép fájlban van és Apache küldi ki. (És folytathatnám, hogy ha diavetítést csinál, akkor egyszerre csak egyet, majd js-el cserélgetve, ..., de itt klattyolgatós minik vannak.)
47

A memória számolásba nem

tgr · 2012. Aug. 23. (Cs), 20.55
A memória számolásba nem vettetek bele egy gyakori esetet, mi van ha 2 látogatód nézi az oldalt egyszerre, és nem 6, hanem 12 kép letöltés megy párhuzamossan? Vagy ha így még épp elférsz, mi van ha 3 látogatód van? Nagyon hamar eljutsz egy olyan látogató számhoz ahol a felvázolt megoldásod nem alkalmazható.


Limitálni kell a PHP processzek számát, nem egy nagy varázslat. A többi addig várakozik. Simán alkalmazható (és alkalmazzák is) nagy látogatószám mellett, egy sor előnye van: külön szerver(ek)en futtathatod a képgenerálást, ha bármi megfekszik benne, az oldalad még mindig olvasható marad (egy galériánál pont nem érsz sokat ezzel, de egy blogszolgáltatónál pl. nagyon nem mindegy), sokkal gyorsabban töltődik az oldal (nem kell a HTML kiküldésével megvárni a thumbnailek elkészültét). Nem is beszélve arról, ha statikusan cache-elni akarod a tartalmat, a képek meg változhatnak közben.