tags:

views:

156

answers:

4

Today I added a new feature in the content management system I'm building. Depending on where you are uploading an image to, PHP will resize the image to fit the designated location. It works quite well, but when I try to upload a larger image, as in a 3MB image, I'm getting a fatal error:

Fatal error: Allowed memory size of 134217728 bytes exhausted 
(tried to allocate 42520 bytes) in...

I'm thinking 128MB of memory is quite a lot, considering I don't run that much... at least I don't think so. It tried to allocate another 42520 bytes for the resizing process, but failed.

My question is should I (A) increase the limit or (B) re-evaluate why I'm using so much memory in the first place? Is 128MB a good number or is it too large/too little?

Thanks, Ryan

RESOLUTION

I concluded that 128MB is really too much for resizing an image and I was so focused at looking at other options... like exec() options, that I never took a closer look at my "sample" data. Turns out, that even though my large image was only 2.83MB, it was OVER 10000px wide. That's a problem. :)

A: 

You shouldn't ever need that much memory allocated. Re-evaluate your code to reduce it's consumption and make sure you aren't storing data superfluously.

methodin
I will say I'm on a shared host, so I don't know if the 128MB is all mine or for everyone? I'm actually looking into moving everything to a dedicated virtual host, but I want to make sure I understand the problem. Usually, as you suggest, throwing memory at it will not ultimately solve the problem. -Ryan
Ryan S.
Scratch that... the limit is per script. -Ryan
Ryan S.
+2  A: 

How are you resizing the image? I hope you're using a library function for it like imagecopyresampled()? If so, you shouldn't need 128M of RAM to resize a 3M image. It points to you doing something incorrectly or inefficiently.

cletus
I'm actually using a big part of this script right here:http://www.white-hat-web-design.co.uk/articles/php-image-resizing.php
Ryan S.
symcbean
I actually do know what the code does. I'm beyond cutting and pasting. The script does indeed look very clean and is easy to follow, hence why I picked it. The thing is, before I started resizing the image, I could upload a 5MB picture and never had a memory issue. That's not to say that perhaps I was just under the limit. Is there a "monitor" to view a graph or something to see the memory usage per line or so? -Ryan
Ryan S.
+4  A: 

GD stores images as bitmaps in memory, so I wouldn't completely rule out the possibility that with some JPG images (for example, high resolution, highly compressed), the bitmap version could be quite large.

Call memory_get_usage() right before you open & start resizing the image & see if that amount of memory is way too big.

Also just FYI, when the script says "(tried to allocate 42520 bytes)", that doesn't mean it just needed 42520 more bytes to run successfully. It just means at that moment it needed 42520 more bytes. A bit later it might have tried to allocate more memory. So, just adding 42520 more bytes to the memory total likely wouldn't have fixed anything.

Pickle
Very helpful! I'm going to try that right now and reply back with results!
Ryan S.
File: 940KB. Before: 89724. After: 2321281.File: 2.83MB. Before: 89724. After: ERROR.My new question: How does it jump from 2.2MB to over 128MB based on image size? And is the problem related to how the script resizes the image? -Ryan
Ryan S.
Well, just as note - the script has to UNPACK the image into a bitmap. I can easily make a small gif that uses 1gb memory unpacked. Then it has to repack.
TomTom
In my case, what are my options? -Ryan
Ryan S.
Pickle
A: 

Rough estimate of how much memory is consumed by a TrueColor image:

width x height x 4

If your users are informed about the maximum dimensions (in pixels) of an uploaded image, then you can determine the minimum RAM you have to allocate.

BTW, consider the variables being used in operations like format conversion, copying, etc.

stillstanding
Is it normal that does function imagecreatefromjpeg() is the most resource intensive? Before that function runs, I'm using 91316 bytes of the available 128MB. Does this function really need more than 128MB for a 2.82MB image? Are there any alternative options? -Ryan
Ryan S.
A 2.82MB compressed image is not indicative of how much RAM (uncompressed image) is needed. A 1280x800 TrueColor image consumes 4MB in RAM but may have a physical size of only 256KB on disk due to JPEG compression.
stillstanding
So it's based on its physical size. -Ryan
Ryan S.