views:

121

answers:

4

All,

I am working on a Zend Framework based web application. We keep encountering out of memory errors on our dev server:

Allowed memory size of XXXX bytes exhausted (tried YYYY...

We keep increasing memory_limit in php.ini, but it is now up over 1000 megs. What is a normal memory_limit value? What are the usual suspects in php/Zend for running out of memory? We are using the Propel ORM.

Thanks for all of the help!

Update I cannot reproduce this error in my windows environment. If I set memory_limit low (say 16M), I get the same error, but the "tried to allocate" amount is always something reasonable. For example: (tried to allocate 13344 bytes) If I set the memory very low on the (Fedora 9) server (such as 16M), I get the same thing. consistent, reasonable out of memory errors. However, even when the memory limit is set very high on our server (128M, for example), maybe once a week, I will get an crazy huge memory error: (tried to allocate 1846026201 bytes). I don't know if that might shed any more light onto what is going on. We are using propel 1.5. It sounds like the actual release is going to come out later this month, but it doesn't look like anyone else is having this problem with it anyway. I don't know that Propel is the problem. We are using Zend Server with php 5.2 on the Linux box, and 5.3 locally.

Any more ideas? I have a ticket out to get Xdebug installed on the Linux box.

Thanks,

-rep

A: 

What exactly is your application doing at the time it runs out of memory. There can be a lot of causes for this. I'd say most common would be allocating too much data to an array. Is your application doing anything along those lines.

KThompson
The problem is, this error is intermittent, and never in the same place. Sometimes it even occurs when logging out. Over a span of two or three weeks, it has probably happened less than 10 time, so it is difficult to say what is happening when the memory runs out. What do you think would be the best approach to narrowing down offending code?
RepDetec
The past two times I have gotten the error, it has been for the following line:require_once 'Security/Auth.php';Do you think that there is something to this, or that it is just because that is one of the first lines that gets touched?
RepDetec
If your error logs aren't revealing anything you could profile your php code. It can help you determine how long functions are running and morehttp://stackoverflow.com/questions/133686/what-is-the-best-way-to-profile-php-code
KThompson
Is there any way to get a heap dump in php? Or get at least get a dump of the entire session?
RepDetec
from what I know php has a var_dump($var) function that will show you everything contained in a particular variable but thats it. I STRONGLY recommend xdebug. You have to add the extension to php unless your installation already has it. It can tell you what functions were running, for how long, and how much memory they used. It outputs to a file that you can read or to another format that you can give to WinCacheGrind(Windows), KCacheGrind(Unix) or MacCallGrind(Mac) which can generate graphs, charts etc.
KThompson
The problem is, we are running Zend Server CE (PHP 5.3), and when I try to install the XDebug dll, I am getting a conflict because it was built with VC9 (or VC6 depending on the download). Does anyone have a dll built with VC8 (which is what the Zend engine needs)? Or does anyone have experience compiling XDebug in Windows? I am missing a bunch of header files and don't know where to find them. Thanks!
RepDetec
I am unaware nor could I find any solutions for your XDebug problem. Here's an alternative you can try. http://us.php.net/apd
KThompson
I reinstalled Zend Server CE to get php 5.2 on my system. I downloaded the XDebug dll for it. My php.ini looks like this:zend_extension_ts="C:\Zend\ZendServer\lib\php_xdebug-2.0.1-5.2.1.dll"zend_extension="C:\Zend\ZendServer\lib\ZendExtensionManager.dll"However, when I restart the webserver, XDebug still does not show up under phpinfo(). Any ideas?
RepDetec
KThompson
I followed the instructions and with this dll: php_xdebug-2.0.5-5.2-nts.dll, Xdebug still will not show up with phpinfo(), but it will show up (twice) if I enter php -m at the commandline. I still can't really get anything different to happen in my app though. I get an error that "xdebug_dump_superglobals()" is undefined.
RepDetec
Did you disable Zend Optimizer? Also, have you tried Zend Debugger instead of XDebug?
KThompson
I did disable Zend Optimizer, but still couldn't get XDebug working. I just decided to cut my losses and am now trying to get Zend Debugger working. It is green, and looks good. Now I am just trying to figure out how to get a dump or write to a log (I don't have Zend Studio).
RepDetec
Have you seen this? http://www.zend.com/en/products/server/zend-server-code-tracing
KThompson
We are only using Community Edition and it does not include code tracing. I don't think the client is going to want to spring for that. It's too bad too. That looks pretty awesome.
RepDetec
Facebook has an internally developed profiler here: http://pecl.php.net/package/xhprofIt looks promising
KThompson
A: 

You have one of two things happening, perhaps both:

  1. You have a runaway process somewhere that isn't ending when it should be.
  2. You have algorithms that throw lots of data around, such as huge strings or arrays or objects, and are making needless copies instead of processing just what they need and discarding what they don't.
staticsan
It looks like the line that is exhausting memory is always a require_once for one of two files. What actually happens during a "require_once?" Doesn't it just parse the file?
RepDetec
It executes the file. Most of the time, such files are simply function and class declarations, but they can also have immediate code, too. I've seen some frameworks do stupid things with huge objects just to initialize themselves. I wouldn't have thought Zend would have that problem - it might be loading a huge amount of data from somewhere.
staticsan
+3  A: 

Generally speaking, with PHP 5.2 and/or PHP 5.3, I tend to consider than more than 32M for memory_limit is "too much" :

  • Using Frameworks / ORM and stuff like this, 16M is often not enough
  • Using 32M is generally enough for the kind of web-applications I'm working on (typical websites)
  • Using more than 64M means the server will not be able to handle as many users as we'd like.


When, it comes to a script reaching memory_limit, the usual problem is trying to load too much data into memory ; a couple of examples :

  • Loading a big file in memory, with functions such as file or file_get_contents, or XML-related functions/classes
  • Creating a too big array of data
  • Creating too many objects

Considering you are using an ORM, you might be in a situation where :

  • You are doing some SQL query that returns a lot of rows
  • Your ORM is converting each row in objects, putting those in an array
  • In which case a solution would be to load less data
    • using pagination, for instance
    • or trying to load data as arrays instead of objects (I don't know if this is possible with Propel -- but it is with Doctrine ; so maybe Propel has some way of doing that too ? )
Pascal MARTIN
A: 

I think this has something to do with deployment from cruise control. I only get the very high (on the order of gigs) memory error when someone is deploying new code (or just after new code has been deployed). This makes a little bit of sense too since the error always points to a line that is a "require_once." Each time I get an error: Fatal error: Out of memory (allocated 4456448) (tried to allocate 3949907977 bytes) in /directory/file.php on line 2

I have replaced the "require_once" line with: class_exists('Ingrain_Security_Auth') || require('Ingrain/Security/Auth.php');

I have replaced that line in 3 files so far, and have not had any more memory issues. Can anyone shed some light into what might be going on? I am using Cruise Control to deploy.

RepDetec