Is my Apache2 setup leaking memory?
Recently, I've noticed that my apache uses absurd amounts of memory on my Linode server (80MB more than it used to), and restarting apache2 seems to fix the issue.
I run SVN over apache, as well as mysql and tomcat on the server, but neither seems to be the issue. How do I go about debugging where apache is losing memory? Aside from SVN, it's really only hosting a wordpress blog, so I don't see where the leak could be occurring. I used a default install from the ubuntu 8.04 repositories.
Any help?
Solution 1:
A nuance of Apache's memory handling means it always appears to be eating more and more memory - top's VIRT value is often high when using prefork.c
(which I assume you are):
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
10385 apache 15 0 376m 48m 3932 R 20.3 1.2 0:01.34 httpd
10423 apache 16 0 376m 46m 4576 S 15.0 1.2 0:01.09 httpd
10153 apache 15 0 337m 61m 4672 S 11.6 1.6 0:03.94 httpd
10419 apache 15 0 383m 54m 4696 S 11.6 1.4 0:01.00 httpd
The value you want to monitor is RES - this is the size of the greatest amount of memory that child thread has consumed (in my case, PHP is run as part of that thread, hence the "bloat" as libraries and data are loaded). The thread does not release the allocated memory, however when the apache process kills the thread after its maxrequests as per
<IfModule prefork.c>
MaxRequestsPerChild 1000
the thread will return to its native memory consumption. This is the same effect as restarting apache, although a restart involves a temporary loss of service (nothing is listening on port 80) whereas MaxRequestsPerChild only controls child threads, ensuring that there is still a service listening on port 80 (or wherever it's configured to listen).
To lower apache's total memory usage, ensure you are only loading the apache modules you require, and monitor apache's threads while you run a very large PHP script (ini_set('memory_limit', '128M');
then recursively load data into an array - that should do it). Then, during real world usage, lower the MaxRequestsPerChild
value until you see your apache RES
at a reasonable level. Don't forget this is only lowering the possibility of a child thread running a large script at the beginning of its "life" (the more children that do this, the more total memory apache uses),
Here are some useful parameter tuning articles:
- OnLamp LAMP stack tuning
- Low apache memory usage
- Apache max performance
- High server memory usage tips