PHP, Apache 2, memory and APC

php.internals

Brian Moon

20 years ago
I have some questions about the Apache 2 SAPI. We had been using apache_child_terminate to control memory usage with Apache 1.3. This function is not available with the Apache 2 SAPI. Is this function just not offered in the Apache 2 API? If it is offered and there is some gotcha or simply work to be done, I would be happy to roll up my sleeves, dust off my C hat and submit a patch. I just need a push in the right direction. I can't really find an Apache 2 SAPI API reference anywhere. Because we can not use this function, we decided to try out the worker MPM to help our memory woes. So far, we have had great success with it. Our limited extension list appears to have no problems. The memory usage on our web servers is down about 15% now. However, this meant we can not use APC. Are there plans to make APC work with ZTS? I know APC is not developed by the PHP group, but I also know Rasmus is involved and I hoped this would find him the easiest. Speaking of those memory woes, I know there is a lot of confusion about that problem with PHP. Can one of the core guys explain why the PHP memory manager can't give the memory back like a simple emalloc can? Is there some big gain in performance we are getting because of this? If there is a previous post on this list or elsewhere, feel free to point me to it. Thanks,
-- Brian Moon dealnews.com -------------- How to go broke saving money. http://dealnews.com/

Rasmus Lerdorf

20 years ago
Brian Moon wrote:
> I have some questions about the Apache 2 SAPI. We had been using > apache_child_terminate to control memory usage with Apache 1.3. This > function is not available with the Apache 2 SAPI. Is this function just > not offered in the Apache 2 API? If it is offered and there is some > gotcha or simply work to be done, I would be happy to roll up my > sleeves, dust off my C hat and submit a patch. I just need a push in > the right direction. I can't really find an Apache 2 SAPI API reference > anywhere. > > Because we can not use this function, we decided to try out the worker > MPM to help our memory woes. So far, we have had great success with it. > Our limited extension list appears to have no problems. The memory > usage on our web servers is down about 15% now.
That makes very little sense. An individual Apache process will use the same amount of memory whether it is an Apache1 process or an Apache2 Worker process. It probably uses more under Apache2 ZTS actually (and it runs slower). The only difference is that the threads within the Apache2 ZTS process will re-use each others' memory while under Apache1 the memory will only be reused by requests to the same process. Trying to hand it back to the OS via an sbrk or something is usually rather redundant since another request will come along and allocate that same amount again. If you are running out of system memory the only realistic recourse is to lower the number of concurrent processes. I tend to never run more than about 50 per machine, depending on the size of the machine. Trying to run more doesn't win you anything. You are better off serving less concurrent requests faster on each of your machines behind your load balancer.
> However, this meant we can not use APC. Are there plans to make APC > work with ZTS? I know APC is not developed by the PHP group, but I also > know Rasmus is involved and I hoped this would find him the easiest.
I have no plans to work on ZTS stuff. Work has been done on it in the past though and I know it works in ZTS mode at least under Windows.
> Speaking of those memory woes, I know there is a lot of confusion about > that problem with PHP. Can one of the core guys explain why the PHP > memory manager can't give the memory back like a simple emalloc can?
emalloc is the PHP memory manager. Did you mean malloc? Standard malloc()/free() doesn't give memory back to the system. If your process mallocs 100M and then frees that memory, your process still hangs onto that 100M until it exits (with some caveats/exceptions on that, but generically that is how UNIX works). -Rasmus

Ilia A.

20 years ago
Rather then terminating Apache request yourself, you can use universal Apache configuration directives that allow you to restrict memory utilization of an Apache process. Ilia

Brian Moon

20 years ago
Ilia Alshanetsky wrote:
> Rather then terminating Apache request yourself, you can use universal > Apache configuration directives that allow you to restrict memory > utilization of an Apache process.
Hmmm, the ones I looked at seemed to prohibit a process from growing above a certain size. Can you point me to them? I don't want to prohibit a process from using what it needs (to a point). I need simply need a child to terminate after it has gone above a certain threshold. We found that the norm for our applications was 10-15MB. Usage above that was the exception. Some applications (especially when they were generating cache that had gone stale) would need more for a brief period. I don't want to stop that. Brian.

Rasmus Lerdorf

20 years ago
Brian Moon wrote:
> Ilia Alshanetsky wrote: >> Rather then terminating Apache request yourself, you can use universal >> Apache configuration directives that allow you to restrict memory >> utilization of an Apache process. > > Hmmm, the ones I looked at seemed to prohibit a process from growing > above a certain size. Can you point me to them? I don't want to > prohibit a process from using what it needs (to a point). I need simply > need a child to terminate after it has gone above a certain threshold. > > We found that the norm for our applications was 10-15MB. Usage above > that was the exception. Some applications (especially when they were > generating cache that had gone stale) would need more for a brief > period. I don't want to stop that.
I still think your best bet is to simply allow for the top watermark for each of your processes and configure your machines with enough ram to handle perhaps a smaller number of processes. Or fix your code to use less if that high watermark is too high. Killing processes seems like a very crude fix here. -Rasmus

Xuefer Tinys

20 years ago
think of using fastcgi? u can have more user->httpserver concurrent connection than http->fastcgi. 5-20 php-fastcgi is enough in some case, with thread disabled, while u can run apache2 mpm worker.