php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #59878 simple code leaks memory
Submitted: 2011-08-01 17:01 UTC Modified: 2015-01-18 04:22 UTC
Votes:8
Avg. Score:5.0 ± 0.0
Reproduced:8 of 8 (100.0%)
Same Version:5 (62.5%)
Same OS:3 (37.5%)
From: glen at delfi dot ee Assigned: mkoppanen (profile)
Status: No Feedback Package: imagick (PECL)
PHP Version: Irrelevant OS: PLD Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: glen at delfi dot ee
New email:
PHP Version: OS:

 

 [2011-08-01 17:01 UTC] glen at delfi dot ee
Description:
------------
$ php ~/im.php
Imagick 3.0.1
MEM: 630.96 KiB - START
MEM: 631.72 KiB - created $im
MEM: 631.93 KiB - Fetched width
MEM: 632.14 KiB - Fetched height
MEM: 632.14 KiB - destroyed $im


Reproduce code:
---------------
#!/usr/bin/php
<?php
function mem($msg) {
        printf("MEM: %.2f KiB - %s\n", memory_get_usage() / 1024, $msg);
}

$input_file = "s.gif";

$ext = new ReflectionExtension('imagick');
echo "Imagick ", $ext->getVersion(), "\n";

mem('START');
$im = new Imagick($input_file);
mem('created $im');
$src_width = $im->getImageWidth();
mem("Fetched width");
$src_height = $im->getImageHeight();
mem("Fetched height");
$im->destroy();
mem('destroyed $im');


Expected result:
----------------
i'd expect memory being released if $im->destroy() is called

i tested this with various extension versions, 2.2.2, 3.0.1, 
3.1.0b1 - all of them leaked memory


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-08-01 17:07 UTC] mkoppanen@php.net
Hello,

the destroy method doesn't actually destroy the internal structures as that would cause problems if the object is accessed after destroy.

Instead the method reduces the reference count of the object (you are better off doing unset ($im)). Also very little memory usage difference will be visible when the object is freed as Imagick doesn't use PHP allocation mechanisms for majority of the memory so therefore the memory allocated for images etc will not be visible there.
 [2011-08-01 17:31 UTC] glen at delfi dot ee
yet, even unset() does not release memory back,

if i run imagick in a loop, and assign it to _same_ 
variable, that should release memory as the same variable is 
overassigned ($im = new Imagick()).

so with this code, i'd expect memory being returned back 
when FINISH is reached, but it isn't.

mem('START');
for ($i = 0; $i < 10; $i++) {
        $im = new Imagick($input_file);
        mem('created $im');
        $im->destroy();
        mem('destroyed $im');
        unset($im);
        mem('unset $im');
}
mem('FINISH');

$ ./im.php
Imagick 3.0.1
MEM: 631.02 KiB - START
MEM: 631.98 KiB - created $im
MEM: 631.98 KiB - destroyed $im
MEM: 631.85 KiB - unset $im
MEM: 632.38 KiB - created $im
MEM: 632.38 KiB - destroyed $im
MEM: 632.25 KiB - unset $im
MEM: 632.77 KiB - created $im
MEM: 632.77 KiB - destroyed $im
MEM: 632.65 KiB - unset $im
MEM: 633.17 KiB - created $im
MEM: 633.17 KiB - destroyed $im
MEM: 633.05 KiB - unset $im
MEM: 633.57 KiB - created $im
MEM: 633.57 KiB - destroyed $im
MEM: 633.45 KiB - unset $im
MEM: 633.97 KiB - created $im
MEM: 633.97 KiB - destroyed $im
MEM: 633.84 KiB - unset $im
MEM: 634.37 KiB - created $im
MEM: 634.37 KiB - destroyed $im
MEM: 634.24 KiB - unset $im
MEM: 634.77 KiB - created $im
MEM: 634.77 KiB - destroyed $im
MEM: 634.64 KiB - unset $im
MEM: 635.16 KiB - created $im
MEM: 635.16 KiB - destroyed $im
MEM: 635.04 KiB - unset $im
MEM: 635.56 KiB - created $im
MEM: 635.56 KiB - destroyed $im
MEM: 635.44 KiB - unset $im
MEM: 635.43 KiB - FINISH
 [2011-08-01 23:57 UTC] glen at delfi dot ee
any other hints how to avoid memory consumption when used in 
loop? as if process does not release memory it will go very 
slow as kernel has to swap, and i have to abort process every 
10000 new Imagick() calls... (process size is 4GiB around 
then)
 [2011-08-02 10:09 UTC] glen at delfi dot ee
imho there's still problem, even considering your note, it 
leaks memory
 [2012-03-28 12:29 UTC] vytenis dot darulis at gmail dot com
I can confirm this problem - in our app php-fpm processes have continually 
increasing memory usage, unless one sets max_requests=1000 or so to force regular 
restarting of php child processes. Porting image resize code from imagick to gd 
solved the problem. Last observed using imagick 3.1.0 RC and PHP 5.3.10.
 [2012-03-28 12:48 UTC] vytenis dot darulis at gmail dot com
And by memory usage, I mean VmSize from /proc/$PID/status. FPM child processes 
virtual memory size always increased after running imagick resizing procedure and 
never went down.
 [2013-12-03 11:31 UTC] mike@php.net
-Assigned To: +Assigned To: mkoppanen
 [2015-01-02 17:12 UTC] Danack at basereality dot com
This issue is not reproducible on PHP 5.6.2 with the latest (3.2.0RC1) version of Imagick and the latest version of ImageMagick (6.9.9-0).


If this is still an issue with the latest version of Imagick, please can you specify what versions of ImageMagick and PHP you are using to allow reproduction of this problem.
 [2015-01-05 02:44 UTC] danack@php.net
-Status: Assigned +Status: Feedback
 [2015-01-05 02:44 UTC] danack@php.net
Awaiting feedback.
 [2015-01-10 10:04 UTC] glen at delfi dot ee
➔ cat ./im2.php
#!/usr/bin/php
<?php
function mem($msg) {
        printf("MEM: %.2f KiB - %s\n", memory_get_usage() / 1024, $msg);
}

$input_file = "s.gif";

$ext = new ReflectionExtension('imagick');
$v = Imagick::getVersion();
echo $v['versionString'], "\n";
echo "Imagick ext ", $ext->getVersion(), " PHP ", PHP_VERSION, "\n";

mem('START');
for ($i = 1; $i < 10; $i++) {
        $im = new Imagick($input_file);
        mem('created $im');
        $im->destroy();
        mem('destroyed $im');
        unset($im);
        mem('unset $im');
}
mem('FINISH');

➔ ./im2.php
ImageMagick 6.8.7-6 Q16 x86_64 2014-09-14 http://www.imagemagick.org
Imagick ext 3.1.2 PHP 5.5.17
MEM: 244.76 KiB - START
MEM: 245.25 KiB - created $im
MEM: 245.25 KiB - destroyed $im
MEM: 244.95 KiB - unset $im
MEM: 245.25 KiB - created $im
MEM: 245.25 KiB - destroyed $im
MEM: 244.95 KiB - unset $im
MEM: 245.25 KiB - created $im
MEM: 245.25 KiB - destroyed $im
MEM: 244.95 KiB - unset $im
MEM: 245.25 KiB - created $im
MEM: 245.25 KiB - destroyed $im
MEM: 244.95 KiB - unset $im
MEM: 245.25 KiB - created $im
MEM: 245.25 KiB - destroyed $im
MEM: 244.95 KiB - unset $im
MEM: 245.25 KiB - created $im
MEM: 245.25 KiB - destroyed $im
MEM: 244.95 KiB - unset $im
MEM: 245.25 KiB - created $im
MEM: 245.25 KiB - destroyed $im
MEM: 244.95 KiB - unset $im
MEM: 245.25 KiB - created $im
MEM: 245.25 KiB - destroyed $im
MEM: 244.95 KiB - unset $im
MEM: 245.25 KiB - created $im
MEM: 245.25 KiB - destroyed $im
MEM: 244.95 KiB - unset $im
MEM: 244.95 KiB - FINISH
➔ 

the php version does not seem to matter, so i guess extension version is what matters (fixed the leakage). so here output from same system but different php version:

➔ php53 ./im2.php
ImageMagick 6.8.7-6 Q16 x86_64 2014-09-14 http://www.imagemagick.org
Imagick ext 3.1.2 PHP 5.3.29
MEM: 632.98 KiB - START
MEM: 633.94 KiB - created $im
MEM: 633.94 KiB - destroyed $im
MEM: 633.41 KiB - unset $im
MEM: 633.94 KiB - created $im
MEM: 633.94 KiB - destroyed $im
MEM: 633.41 KiB - unset $im
MEM: 633.94 KiB - created $im
MEM: 633.94 KiB - destroyed $im
MEM: 633.41 KiB - unset $im
MEM: 633.94 KiB - created $im
MEM: 633.94 KiB - destroyed $im
MEM: 633.41 KiB - unset $im
MEM: 633.94 KiB - created $im
MEM: 633.94 KiB - destroyed $im
MEM: 633.41 KiB - unset $im
MEM: 633.94 KiB - created $im
MEM: 633.94 KiB - destroyed $im
MEM: 633.41 KiB - unset $im
MEM: 633.94 KiB - created $im
MEM: 633.94 KiB - destroyed $im
MEM: 633.41 KiB - unset $im
MEM: 633.94 KiB - created $im
MEM: 633.94 KiB - destroyed $im
MEM: 633.41 KiB - unset $im
MEM: 633.94 KiB - created $im
MEM: 633.94 KiB - destroyed $im
MEM: 633.41 KiB - unset $im
MEM: 633.41 KiB - FINISH

➔
 [2015-01-18 04:22 UTC] pecl-dev at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Thu Sep 16 19:03:38 2021 UTC