php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73324 GD excessive memory usage
Submitted: 2016-10-14 18:14 UTC Modified: 2016-10-17 06:41 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:0 (0.0%)
From: ch at aixit dot com Assigned: cmb (profile)
Status: Closed Package: GD related
PHP Version: 7.0.12 OS: *
Private report: No CVE-ID: None
 [2016-10-14 18:14 UTC] ch at aixit dot com
Description:
------------
# tested with different linux distros (debian8, centos6.5)

# PHP 7.0 (tested with different versions of php 7.0)
PHP VERSION: 7.0.12-1+jessie1
IMAGE FILESISE: 205.09K
IMAGE FILETYPE: image/jpeg
IMAGE DIMENSION: 1240x1754

MEMORY USE (CURRENT/PEAK): 355.20K / 1.42M
$img = imagecreatefromjpeg($filename);

MEMORY USE (CURRENT/PEAK): 17.01M / 17.01M
$img = imagescale($img, 3000);
MEMORY USE (CURRENT/PEAK): 65.61M / 82.26M


# Same Imagefile with php 5.6
PHP VERSION: 5.6.26-0+deb8u1

MEMORY USE (CURRENT/PEAK): 230.26K / 504.37K
$img = imagecreatefromjpeg($filename);

MEMORY USE (CURRENT/PEAK): 230.51K / 504.37K
$img = imagescale($img, 3000);
MEMORY USE (CURRENT/PEAK): 230.51K / 504.37K

# configure line
'./configure'  '--prefix=/opt/php-7.0' '--with-config-file-path=/opt/php-7.0/etc' '--with-config-file-scan-dir=/opt/php-7.0/etc/conf-enabled' '--enable-fpm' '--with-fpm-systemd' '--with-imap=/usr' '--with-imap-ssl' '--with-kerberos' '--with-zlib-dir' '--with-freetype-dir' '--enable-mbstring' '--with-libxml-dir=/usr' '--enable-soap' '--with-curl=shared' '--with-mcrypt=shared' '--with-zlib' '--with-gd=shared' '--with-pdo-mysql' '--with-pdo-pgsql' '--with-mysql-sock=/var/run/mysqld/mysqld.sock' '--with-mysqli' '--enable-sockets' '--with-jpeg-dir=/usr' '--with-png-dir=/usr' '--enable-gd-native-ttf' '--with-openssl' '--with-openssl-dir=/usr' '--enable-inline-optimization' '--with-bz2' '--enable-sysvsem' '--enable-sysvshm' '--enable-sysvmsg' '--enable-pcntl' '--enable-mbregex' '--with-mhash' '--enable-zip' '--with-pcre-regex' '--enable-ftp' '--with-gettext' '--enable-calendar' '--enable-intl' '--enable-exif' '--enable-bcmath' '--enable-dba' '--enable-shmop' '--enable-wddx' '--with-readline' '--with-ldap=shared' '--with-ldap-sasl' '--with-snmp=shared' '--with-xmlrpc=shared' '--with-mhash=shared' '--with-xsl=shared' '--with-pspell=shared' '--with-gmp=shared' '--with-tidy=shared'

# Loaded modules
apcu bcmath bz2 calendar Core ctype curl date dba dom exif fileinfo filter ftp gd gettext hash iconv imagick imapintl json ldap libxml mbstring 
mcrypt mysqli mysqlnd openssl pcntl pcre PDO pdo_mysql pdo_pgsql pdo_sqlite Phar posix readline Reflection session shmop SimpleXML snmp soap sockets
SPL sqlite3 ssh2 standard sysvmsg sysvsem sysvshm tokenizer wddx xml xmlreader xmlwriter Zend OPcache zip zlib 
Zend OPcache


Test script:
---------------
<?php
$filename = "test.jpg";
echo 'Memory usage:' . memory_get_usage() .PHP_EOL;
$img = imagecreatefromjpeg($filename);
echo 'Memory usage:' . memory_get_usage() .PHP_EOL;


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-10-15 09:19 UTC] cmb@php.net
-Status: Open +Status: Feedback -Assigned To: +Assigned To: cmb
 [2016-10-15 09:19 UTC] cmb@php.net
A high memory consumption is to be expected when dealing with
rather large images, because for truecolor images internally each
pixel requires 32 bit, resulting in 8,699,840 bytes. When the
image is scaled up to 3000*4243 pixels, the pixels consume
50,916,000 bytes. Because imagescale() creates a new image, both
images will have to be retained in memory, until the assignment to
$img (which will release the original image immediately).

Considering this, the values reported by 7.0 appear pretty much to
be expected. The values reported by 5.6 would be wrong, but it's
not clear to me how you've measured these. memory_get_usage() and
memory_get_peak_usage() report sane values for me (on Windows).

Note also, that when PHP is built with a system libgd, the
$real_usage parameter of these function would have to be set to
TRUE; otherwise the memory used by libgd will not be properly
reported, because it is not allocated by the Zend memory manager,
but plain malloc() and friends.
 [2016-10-17 06:41 UTC] ch at aixit dot com
-Status: Feedback +Status: Closed
 [2016-10-17 06:41 UTC] ch at aixit dot com
I was using memory_get_usag(false) for the first messuring but the memory usage was just a little lower copmared to values from memory_get_usag(true).

Looks like debian GD extension uses a not bundles GDLib. So the used memory usage is not shown properly and its bypassing the php memory_limit setting.

PHP VERSION: 5.6.26-0+deb8u1
GD VERSION: 2.1.1-dev

so self-builded php7 works properly on memory_get_usage(true).

Afterwards I build a 5.6.26 from source and compared it with 7.0.12

# PHP7 self-build
PHP VERSION: 7.0.12-1+jessie1
GD VERSION: bundled (2.1.0 compatible)
MEMORY LIMIT: 128M
IMAGE FILESISE: 205.09K
IMAGE FILETYPE: image/jpeg
MEMORY USE (CURRENT/PEAK): 2.10M / 2.10M
$img = imagecreatefromjpeg($filename);
IMAGE DIMENSION: 1240x1754

MEMORY USE (CURRENT/PEAK): 18.87M / 18.87M
$img1 = imagescale($img, 3000);
MEMORY USE (CURRENT/PEAK): 83.89M / 83.89M


# PHP5 self-build
PHP VERSION: 5.6.26-1+jessie1
GD VERSION: bundled (2.1.0 compatible)
MEMORY LIMIT: 128M
IMAGE FILESISE: 205.09K
IMAGE FILETYPE: image/jpeg
MEMORY USE (CURRENT/PEAK): 262.14K / 786.43K
$img = imagecreatefromjpeg($filename);
IMAGE DIMENSION: 1240x1754

MEMORY USE (CURRENT/PEAK): 11.27M / 11.27M
$img1 = imagescale($img, 3000);
MEMORY USE (CURRENT/PEAK): 75.24M / 75.24M


Sorry for the inconvenience. The memory usage is not as excessive as it was in the comparison to php5.6.26 (debian version).
 
PHP Copyright © 2001-2022 The PHP Group
All rights reserved.
Last updated: Mon Jul 04 03:03:50 2022 UTC