'ello all.

Well, I have been distributing a web software package and 95% of the time I don't hear about problems. But this one has me a little befuddled.

When the user is uploading an image greater than 300KB, this error is generated.

Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 6400 bytes) in /home/xxxxx/public_html/xxxxx-xxxxx/xxxxx/classes/Image.php on line 113

Line 113 makes a call to imagecreatefromjpeg.

This is not a widespread issue ... just seems to be happening for this one person.

You can temporarily view the phpinfo at http://bassworld.puslapiai.lt/mundas-tech/parde/phpinfo.php

Anyone have any ideas why an image < 300KB eats up all 8MB of memory?

TIA!

    Kudose wrote:

    Anyone have any ideas why an image < 300KB eats up all 8MB of memory?

    Poor coding before the point in the script that deals with the <300KB image.

      try sticking some [man]memory_get_usage[/man] calls throughout the script up to that point and see if you can find where it grows. just an instance of php will use a few mb of memory for loading the engine and parsing the script, then all the variables and internal data it needs to store to run your program will add up.

        Also note that the PHP image functions work with the uncompressed image (essentially a bitmap of it), so it's probably using significantly more memory than just the 300KB storage size of the JPEG. While I'm sure that one command is not eating up several megs of memory, by itself it could be accounting for something closer to 1 meg than it is to 300KB.

          Ouch.

          No offense, but I don't think that's the case. I don't want to start an argument or post up lots of code.

          I could be wrong, but I don't think that 70KB of code (all files sizes included added together) and a 300KB image would make the server use 8Megs of memory.

          Could it?

          edit lots of posts while viewing this one ... this post might not be relevant anymore. /edit

            Without seeing any code, it's pretty hard for anyone to evaluate where exactly the memory is getting eaten up. All we know is where it finally goes over the limit. As per a reply in your cross-post of this problem, try metering your code with some memory_get_usage() calls to see if you can narrow down where things are munching up big chunks of memory.

              Kudose wrote:

              I don't think that 70KB of code (all files sizes included added together) and a 300KB image would make the server use 8Megs of memory.

              The size of the code itself isn't what uses up all the memory - it's what that code makes the system do. I could write <1KB of code that chews up all 8MB of memory very quickly.

              As NogDog said, you can start adding various checkpoints with echo'ing out [man]memory_get_usage/man in different parts of the script... when you see a large jump, something before that echo() used up a lot of memory.

              If you can isolate a part of the code using this technique, post it here and we might be able to find a better solution. Otherwise... I don't know what else to say without seeing the code.

              EDIT: Also, I merged this thread with a duplicate. Please don't crosspost. Thanks.

                I didn't realize that I had cross posted. If I did, it was by accident, I was having some issues getting this thread started. Sorry for that.

                Thanks for the suggestions on memory_get_usage(), I will try that out as soon as I can.

                edit
                Thanks for the tip on the image functions using a uncompressed version of the image. This will help significantly.
                /edit

                  Thanks again for your suggestions ... here is some code and the output.

                  function resize($height = 300, $width = 400){
                        /** If array is not passed, use a variable */
                        $image = $this->path.$this->source['name'];
                        echo memory_get_usage().'<br />';
                        /** Create a blank image */
                        $resize = imagecreatetruecolor($width, $height);
                        echo memory_get_usage().'<br />';
                        $quality = 75;
                        $size = getimagesize($image);
                        switch ($size['mime']) {			
                    			case 'image/jpeg':
                    			echo memory_get_usage().'<br />';
                    			$im = imagecreatefromjpeg($image);
                    			imagecopyresampled($resize, $im, 0, 0, 0, 0, $width, $height, $size[0], $size[1]); // Resample the original JPEG
                    			imagejpeg($resize, $image, $quality); // Output the new JPEG
                    			echo memory_get_usage().'<br />';
                    			break;
                  
                  		case 'image/jpg':
                  		$im = imagecreatefromjpeg($image);
                  		imagecopyresampled($resize, $im, 0, 0, 0, 0, $width, $height, $size[0], $size[1]); // Resample the original JPEG
                  		imagejpeg($resize, $image, $quality); // Output the new JPEG
                  		break;
                  
                  		case 'image/png':
                  		$im = imagecreatefrompng($image);
                  		imagecopyresampled($resize, $im, 0, 0, 0, 0, $width, $height, $size[0], $size[1]); // Resample the original PNG
                  		imagepng($resize, $image, $quality); // Output the new PNG
                  		break;
                  	}
                  	imagedestroy($im);
                  
                  	return true;
                  }

                  That is obviously a function in my class, but it should suffice for the example usage of my code.

                  Here is the output of all of the calls to get_memory_usage before it dies:

                  436920
                  1046680
                  1047216
                  
                  Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 6400 bytes) in /home/xxxxx/public_html/xxxxx-xxxxx/xxxxx/classes/Image.php on line 116

                  Unfortunately, I cannot attch the image I am using as it is greater than the thread allows. It is 342KB. Should I post more code or is this enough to shed some light on what's going on?

                  Thanks again.

                    Whew - I almost went insane there. What happens is that your post (and the duplicates you tried to submit - 3 or 4, wasn't it? - were flagged for spam. It was rather humorous, though, because suddenly I started receiving e-mails every minute with the same post content... as if PHPBuilder's servers had gotten stuck in some demonic e-mailing loop.

                      Ok ... that's good to know. I was getting so frickin mad because it didn't say anything ... there was just no post.

                        What are the x/y dimensions of the offending image? (Note that the resulting image will be 300x400x3=360000 bytes uncompressed; I just dug up a random 342kB JPEG lying around and its dimensions are 1586x1062 pixels. At three bytes per pixel that's nearly four MB of raw data right there.

                        Just a couple of side notes: if you handle two cases in a switch in exactly the same way, it's not necessary to duplicate the code.

                        switch($foo)
                        {
                        	case 1:
                        	case 2:
                        	case 3:
                        		// Do something for 1, 2, 3
                        		break;
                        	case 4:
                        		// Do something for case 4
                        		break;
                        	case 5:
                        	case 6:
                        		// Do something for cases 5 and 6
                        }
                        

                        Is perfectly valid.

                        Also, [man]getimagesize[/man] also returns a numeric value representing the image type: it would be more efficient to use this than attempting to match the MIME string.

                          Hmm. I see your point.

                          My offending image was 342KB @ 1600 x 1200 =/ 5.625MB

                          So, although my code isnt the most efficient, I'm not really doing much wrong here. It is all because the image, uncompressed, is using almost 6 Megs by itself? Then add the PHP engine and all of the scripts together and boom ... over 8MB used. Am I following you?

                          Also, thanks for the tip on [man]getimagesize[/man].

                          🙂

                            Write a Reply...