A PHP imagecreatefromjpeg() utasítása a Debian 9 disztribúcióval szállított PHP 7.0 alatt úgy működik, hogy nem tölti be a képet a memóriába. Más, helyben fordított PHP verziókkal azonban a parancs annyi memóriát felhasznál, amekkora a kép tárolásához szükséges, ugyanazon php.ini mellett is.
Egy régebbi Ubuntu disztribúcióban az 5.3-as PHP ugyanígy viselkedik, azaz az imagecreatefromjpeg() parancs külön memória allokálása nélkül nyitja meg a képet.
Kerestem a php fordítási opciói között olyan paramétert, amivel ezt befolyásolni tudom. Nem találtam.
Tud valaki magyarázatot a jelenségre? Hogyan oldhatom meg, hogy az általam fordított php ugyanúgy kezelje a képeket, mint a disztribúció által fordított?
Én egy 3000x2000 pixeles jpg képpel teszteltem, a következő PHP kóddal:
<?php
printf( 'Php verzio: %s Memory_limit:%s<br>', phpversion(), ini_get( 'memory_limit' ) );
printf( 'Start: %dKB<br>', round(memory_get_usage()/1024) );
list($w, $h) = getimagesize( 'src.jpg' );
$orig = imagecreatefromjpeg( 'src.jpg' );
printf( 'Size (%dx%d): %dKB<br>', $w, $h, round(memory_get_usage()/1024) );
A kimenetem pedig a disztribúció 7.0-ás php moduljával:
Php verzio: 7.0.33-0+deb9u3 Memory_limit:64M
Start: 352KB
Size (3000x2000): 354KB
Más PHP-k esetén azonban kb 30MB memória szükséges a végén.
- 801 megtekintés
Hozzászólások
> imagecreatefrompng( 'src.jpg' );
? :)
Nem lehet, hogy az a hiba, hogy a képet nem sikerül betölteni, és közben el van nyelve a warning? Én gondoltam kipróbálom, letöltöttem egy jpeg-et, és néztem nagyot miért nem m működik.
- A hozzászóláshoz be kell jelentkezni
Igen, mert png-vel is teszteltem, hátha a libjpeg körül van a kutya eltemetve. De nem, png-vel is ugyanez a helyzet. Sorry, a kitett kódba valóban hibásan került.
- A hozzászóláshoz be kell jelentkezni
Ami még lehet, hogy más verziójú gd libbel fordul az ami a repóban van. Nálam Ubuntu alatt (7.3) sem foglal látszólag memóriát.
- A hozzászóláshoz be kell jelentkezni
Egy kép beolvasó funkció szerintem foglal memóriát mert valahova raknia kell a pixeleket. Pláne kitomoritve kell keppontonkent 3-4byte-on.
Szerintem a memória le van képezve egy file-ba akkor nem látod valódi foglalaskent. Ez meg talán PHP beállítás talán gdlib.
- A hozzászóláshoz be kell jelentkezni
Az imagecreatetruecolor() például mindig foglal le memóriát.
Inkább arra gondoltam, hogy amíg csak olvas egy képet, addig létezhet olyan konverzió, ami a koordinátákat fájl pozícióra konvertálja, és közvetlenül a fájlból olvassa ki az adatokat. Bár tömörítés esetén, lehet, hogy ez buta gondolat.
Arra is gondoltam, hogy valamilyen SHM beállítás, de ezen a vonalon sem jutottam előrébb.
- A hozzászóláshoz be kell jelentkezni
Az is lehet, hogy a gd valahogy cache-eli az adatokat, és az imagecreatejpeg nem tölti be a képet amíg nem kezded el használni. Az is lehet, hogy használ memóriát, de nem számít bele abba, amit a php elárul.
- A hozzászóláshoz be kell jelentkezni
Egy verzióváltás során derült ki a jelenség. A program teljesen lefutott a disztribúció PHP verzióján, de memóriahibával leállt a saját fordítású PHP-n. Olyannyira, hogy az eredeti PHP-ban 16MB memória elég a kód lefutásához, de az új környezetben már 48MB memória kell. A különbség kb a forrás kép mérete. De a 16MB memóriában semmiképp sem fér el a 30MB-os kép - amit a teszteléshez is használtam. Tehát biztos, hogy nem tölti be munka közben sem a memóriába.
A PHP használna a memory_limit felett is memóriát? Ez meglepne.
- A hozzászóláshoz be kell jelentkezni
Regen a debianban es szarmazekaiban (5.10-es Ubuntu pl, Debian Sargeban es Woodyban) nem a phpva szallitott GD volt, hanem a rendszer GD-t hasznalta a rendszer. Lehet, hogy ez is okozhat valami elterest.
- A hozzászóláshoz be kell jelentkezni
Ez jó ötlet. Megnéztem, de csak egy gd-t találtam. :(
Megpróbáltam kideríteni a phpinfo()-val, hogy milyen fordítási opciókkal fordították a disztribúció php-ját, de érdekes módon, abból hiányzik a "Configure Command" sor. :O
- A hozzászóláshoz be kell jelentkezni
bar annyira nem ismerem a php lelki vilagat, de belenezve a gd ext kodba, talaltam egy ilyet:
https://github.com/php/php-src/blob/master/ext/gd/gd.c#L1784
phphez van dbg csomag, le tudod debugolni hogy rafut-e erre.
a nev alapjan ez valamit bepakol a memoriaba. en megneznem hogy ez a kod hogy nez ki a 7.0-as phpban, meg a regebbi verziokban.
(az is lehet hogy ubuntu/debianosok belenyulnak ide, es ezert lesz mas a debes viselkedes a sajat forditottol)
--
A vegtelen ciklus is vegeter egyszer, csak kelloen eros hardver kell hozza!
- A hozzászóláshoz be kell jelentkezni
Az "apt-get source php7.0" paranccsal megpróbáltam letölteni a debian saját forrását, de lényegében abban is ugyanezt a kódot találtam. Ez eléggé úgy néz ki, mintha lefoglalná a memóriát, de akkor még kevésbé értem a jelenséget.
- A hozzászóláshoz be kell jelentkezni
itt mi valtozott? mitol kerult a lista tejere 14 perccel ezelotti modositassal? csak en nem latom?
- A hozzászóláshoz be kell jelentkezni
Csak annyi, hogy észrevettem, tudom szerkeszteni az eredeti témát, ezért kijavítottam a hibás kódrészt.
Volt egy új ötletem, hogy mi van, ha nem a PHP kezeli máshogy a memóriát, hanem az opcache. De sajnos nem jött be. Gyorsítással és anélkül is ugyanaz a helyzet. A gyári modulok nem foglalják le a memóriát, az általam fordítottak igen.
Továbbra is teljesen tanácstalan vagyok ennek az okát illetőleg, reprodukálni meg végképp nem tudom. :(
- A hozzászóláshoz be kell jelentkezni
Debian 10 alatt szerettem volna PHP-kat fordítani, de egyik sem sikerült. Ezen felbuzdulva megtaláltam a SURY repozitory-t, ami debian 10 alá tartalmazza 5.6-tól 7.4-ig az össze php-t.
A szépsége igazán az a dolognak, hogy mindegyik PHP verzió memóriatakarékos GD-t tartalmaz! Bár ettől nem derült ki, hogy mi a különbség, de ha bárkinek szüksége van rá, hasznos lehet.
- A hozzászóláshoz be kell jelentkezni