views:

464

answers:

3

I'm getting the 'out of memory' error in php. I know it can be fixed with the likes of ini_set("memory_limit","64M"), but I don't want to, because that much memory for a script is abnormal. I have a few reports that are so huge that I pretty much need that memory, but normally don't.

The problem is: I don't even know which script is consuming that much memory, and no user (yet) has reported an error. I know this is happening only thanks to log_errors (set to true) and error_log (set to a very visible file in my desktop), but it doesn't report which script is the culprit.

Any idea on how to know that?

A: 

It's quite normal for a script to eat more memory than 32M, I recently had that problem using with the GD library wanting to consume more than that when rescaling certain image types, and the very same error was thrown. In your case, I would double the memory, and restrict execution time to something safe (if it hasn't been already). I do this via .htaccess, with these lines:

php_value memory_limit 64M
php_value max_execution_time 30
karim79
A: 

You need a profiler for this. I prefer xdebug. This article explains how to get memory usage information for a PHP script.

Ayman Hourieh
+2  A: 

You probably have some basic algorithm errors, creating large data structures, re-building data as other structures, too much large string manipulations, loading whole files into memory, re-fetching data from storage instead of re-using what was retrieved last time, that sort of thing. And many home-grown database handlers give you the whole dataset returned from your query instead of giving you a dataset resource. This is particularly pernicious with queries that can return way more data than originally envisaged.

Once you profile your code, you can start looking for memory waste. For processing large logging datasets, structure your code to work with one line at a time, so it do (for example) while( $data = mysql_fetch_assoc() ) rather than foreach( $data_rows as $data ). This also lets you use an unbuffered query which will also reduce memory consumption.

The error log should be telling you the script that died. Maybe the Apache error log can help.

staticsan
That's the problem: Apache error log shows nothing, PHP only spews the 'out of memory' error without the script name. I've set php to report even notices along with script names, but doesn't work with this particular error (of course, it's out of memory, it can't do anything else)