Tracking memory leaks in a large codebase

1.2k Views Asked by At

I have a relatively large PHP-codebase (thousands of lines) for an application built with CodeIgniter. To be able to trace preformance issues and to be able to generate statistics and such, the developement-servers run Xhprof. This works fine, provided that the script actually comes to the logging part.

However, I've now come at a situation where the script just times out. On the developement-servers, it just gives a timeout ("Server not found") error, and sometimes even crashes the Apache process. No Xhprof file is generated, the CodeIgniter logging system generates nothing. Error reporting IS enabeled.

On a live enviroment (well, mirror of the live-server), the application actually generates an error:

Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 261900 bytes) in /home/www/application/system/database/drivers/mysql/mysql_driver.php on line 493

This, and having a clue on how to reproduce the error, gives me somewhat of a hunch where to start haunting for a solution. But it's a time consuming job to do.

I'm looking for a way to be able to trace WHERE the actual "memory leak" is happening. Instead of manually debugging line after line. Any suggestions are greatly appreciated.

UPDATE : THE LOW MEMORY OF THE SERVER IS NOT THE PROBLEM. On a developement-server with more memory, the same problem occurs. The problem was an infinite loop, allocating more memory then my server could handle. The question remains: how can these errors be tracked down quickly?

2

There are 2 best solutions below

1
On BEST ANSWER

Use xdebug. As opposed to xhprof, profiling with xdebug produces output as the script runs which means even if the script hangs or times out you will be able to dissect the trace generated up to that point.

See also Profiling with xdebug to get started.

0
On

A common problem with programs that intend to keep statistics is that the keep pointers to everything they touch, which prevents the memory management from reclaiming them. If that's not the case, this probably isn't a leak, it's probably just a runaway allocation. You probably have only a few places that might be doing it. A good start is to replace direct calls to system functions that allocate chunks of memory with your own functions, then instrument those functions, looking for unexpectedly large array allocations.

The quoted limit (32mb) isn't very big by modern standards. It could easily be the case that there's nothing wrong except the process has an unreasonably low limit.