6

I have a PHP app built on Codeigniter 1.7.2, currently in production and live, that seems to have a serious memory leak.

The memory leak is apparent from looking at "top" on the server:

top - 23:42:13 up 26 days, 10:14,  1 user,  load average: 0.00, 0.00, 0.00
Tasks:  54 total,   1 running,  53 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st Mem:   7872040k total,   929748k used,  6942292k free,   142464k buffers
Swap:        0k total,        0k used,        0k free,   214420k cached
PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND 
22740 apache    15   0  308m  63m 5976 S    0  0.8   0:14.05 httpd 

22733 apache    15   0  298m  54m 5968 S    0  0.7   0:13.60 httpd

22736 apache    15   0  296m  52m 5968 S    0  0.7   0:13.89 httpd

22742 apache    15   0  295m  50m 5976 S    0  0.7   0:13.05 httpd

22738 apache    15   0  294m  49m 5968 S    0  0.6   0:13.30 httpd

22744 apache    15   0  293m  48m 5968 S    0  0.6   0:13.11 httpd

So httpd is using 0.8% * 7.9GB of memory or approx 63MB.

I know CI plus my app has a footprint of about 7MB. I know httpd probably has some but can't explain 63MB, plus this number goes up daily if I reboot. Thus I concluded there was a memory leak.

From my understanding of PHP 5.2.x, it doesn't quite do "garbage collection" but will free memory upon function exit and finally on script termination. Also, I know of a few known constructs that can result in a memory leak ("child object destruction", and recursive object references), but I'm not doing anything that fancy. So I'm a bit stumped what the problem could be.

I'm going to try to track it down using XDebug but I'm having some issues installing it on Fedora 8. If anyone can point out some "usual suspects" for true memory leaks in PHP 5.2.x, and/or in Code Igniter...I'm hoping I can get lucky and just find the culprit if I know what to look for (I've googled for known issues in CI but no smoking guns. I did turn off a feature that persisted queries between functions and that helped reduce the footprint but it still seems to be leaking).

[root@web7 ~]# php --version
PHP 5.2.6 (cli) (built: May  8 2008 08:54:23)
    Copyright (c) 1997-2008 The PHP Group
    Zend Engine v2.2.0, Copyright (c) 1998-2008 Zend Technologies

[root@web7 ~]# cat /proc/version
    Linux version 2.6.21.7-2.fc8xen (mockbuild@xenbuilder4.fedora.phx.redhat.com) (gcc version 4.1.2 20070925 (Red Hat 4.1.2-33)) #1 SMP Fri Feb 15 12:34:28 EST 2008
Cœur
  • 37,241
  • 25
  • 195
  • 267
PeterG
  • 772
  • 2
  • 11
  • 28
  • 2
    http://anantgarg.com/2009/03/10/php-xdebug-webgrind-installation/ – Alec Smart Feb 15 '11 at 06:38
  • 1
    It's probably worth you going through the [PHP 5 Changelog](http://php.net/ChangeLog-5.php) and seeing if any of the many memory leaks fixed since 5.2.6 chime with your code... – Matt Gibson Feb 15 '11 at 09:19
  • 2
    Just a couple things. One, the RES column shows the amount of memory being used, so you don't have to calculate it from the percent ^_^. The VIRT column is even more hideous, each process has about 300MB allocated for it. Second, just to make sure you're not looking in the wrong place, you have run the server (or one configured the same) without the offending php app to confirm that the leak doesn't exist, correct? – jswolf19 Feb 15 '11 at 13:16

1 Answers1

2

Have you tried turning profiling on in your controller:

$this->output->enable_profiler(TRUE);

Would be interesting to see if anything crops up in the results of that which shows something is taking a little longer than usual.

Additionally you can always try CodeIgniter 2 which has now been released, the upgrade is backward compatible and has a lot of fixes.

--edit You could also try this: I found an variable “var $save_queries = TRUE;” on line 51 in file /system/database/DB_driver.php

Switching this to FALSE solved the issue for me.

From your controller you can use: $this->db->save_queries = FALSE; Where the leak should be an issue. --edit

dizas
  • 98
  • 5
davzie
  • 116
  • 4
  • Useful in my controllers. The site is using alot of AJAX though, enable_profiler()'s not working there since it echos the results (didn't see a way for it to dump to a logfile or some other method). Thanks though this is a good tool to know about. – PeterG Feb 15 '11 at 21:25