Recently I’ve noticed that httpd processes started to consume massive amounts of memory - after some time pretty much using almost all of the 2GB of RAM the server has and I don’t have any memory left for other stuff. Here’s what top tells me (I have added the “data” column at the end as well):
It seems to me that each httpd process does not free the memory after handling a request. So they all sit at ~270MB which is BAD. Is there a way for me to know where all the memory goes and why it stays that way? I haven’t done any server tweaking lately, so I’m sure it’s not me who messed something up (haven’t had the problem before).
The server is used to serve PHP apps and Apache itself is configured with prefork module and MaxRequestsPerChild is set to 4000.
Those numbers do look pretty high. Profiling your code is a good idea, as is setting up an opcode cache to avoid even loading and reinterpreting the files each time a request comes in. I recommend APC, which is probably going to be bundled with PHP6 as well.
You can also remove all the Apache modules you’re not using. If you haven’t customized Apache much, that’s a lot of them, and can save you some CPU and RAM usage. You also want to minimize directives and if you’re only running one site, don’t allow overrides and just put all your directives in httpd.conf to avoid all the file system checks for .htaccess files.
I run a good handful of web servers and keep them very much maxed out – as much load as they can handle without passing the peak where response time starts to suffer. They average ~20MB of RAM per Apache process.
This works well for one of my servers with ~2GB RAM as well, and 4 CPU cores:
Wait, are you saying what I’m experiencing is normal? I mean why doesn’t Apache release the memory? Or is it supposed not to? Basically, what’s hapening is that when I restart Apache, the memory usage drops to a minimum and as soon as a few requests come (Magento shop) in it skyrockets very quickly. Btw, I already use APC which is set to 128M (it’s a global limit, not a per-httpd-process one), but I doubt it would be a problem.
Magento is a true resource hog. They recommend you set your PHP memory limit to 64MB… that’s 64MB of RAM for a single request! That’s why your Apache processes are so bloated.
If you’re going to stick with Magento, you’re going to pay a high hardware cost for it, as you’re discovering.
Unless it’s never levelling off (in which case your system should be crashing), that’s probably normal behavior. You should be concerned with why Apache needs the OS to allocate it so much memory per process (Magento), not the fact that it isn’t continually releasing and reallocating it for every request. That would be horribly inefficient. I don’t know the kernel level details to tell you definitively, but it seems reasonable.
If you want to prove me wrong, run a Hello World PHP page and have apachebench hit your server for a minute, and see if the memory usage is as high.