Update 2 (3/6/2009): FYI, upgrading to the latest version of Apache (2.2.11) has seemed to significantly slow down httpd.exe memory consumption on the reverse proxy server I have running.
Update 1: Well it appears this has not totally resolved the issues. It seems to have just slowed the rate at which the memory grows, not sure exactly how, but over about a week of time, the httpd.exe process still expands to rather large amounts, which I then in turn have to just restart the service. Frustrating issue … oh well, it’s not nearly as bad as it was.
After a long, long effort to research this problem (try over a year), I have finally found a solution that works to keep the HTTPD.exe child process from growing too large within Windows, which in turn causes inevitable performance issues on the Apache server. Now, I know that the Linux-nerd answer to these problems is to run Apache under, well, Linux instead of Windows. However, I have other functions on my servers that are specific to Windows only, and I don’t want a thousand servers sitting at my house. So I had to come up with another solution. I have not really found a solution to actually solve the memory leak issues themselves often associated with running certain modules (like Mod_Deflate, Mod_SSPI, Mod_Proxy, and others) within Apache in a Windows environment, but this definitely alleviates the headache. In addition to the max memory parameter, I have included some other parameters that have helped increase the network performance of my servers:
MaxMemFree 128
EnableSendfile Off
EnableMMAP Off
Win32DisableAcceptEx
In particular, MaxMemFree makes it possible for you to set the limit on how big you want the HTTPD.exe child process to get before it calls the free() function to clear out the overhead associated with the process. You can decide how big you want the process, I just set mine to 128 to try and keep it as low as possible, but if you want more overhead, that is up to you. If anyone out there knows of any issues associated with using this threshold parameter, please let me know as I do not want to cause admins any headaches. So far on my Apache servers though, especially the front-end reverse proxy server in particular, all seems to be running well and the process stays at an estimated 132 MB without getting any larger. Finally! Before, I just had to setup an automated Apache service restart early every morning to keep the overhead down. But now the process does it itself. Very nice.
Here is what the Apache documentation says about the MaxMemFree parameter:
The MaxMemFree directive sets the maximum number of free Kbytes that the main allocator is allowed to hold without calling free(). When not set, or when set to zero, the threshold will be set to unlimited.
And here is what the Apache documentation says about the other functions shown above:
EnableSendfile:
This directive controls whether httpd may use the sendfile support from the kernel to transmit file contents to the client. By default, when the handling of a request requires no access to the data within a file — for example, when delivering a static file — Apache uses sendfile to deliver the file contents without ever reading the file if the OS supports it.
EnableMMAP:
This directive controls whether the httpd may use memory-mapping if it needs to read the contents of a file during delivery. By default, when the handling of a request requires access to the data within a file — for example, when delivering a server-parsed file using mod_include — Apache memory-maps the file if the OS supports it.
Win32DisableAcceptEx:
AcceptEx() is a Microsoft WinSock v2 API that provides some performance improvements over the use of the BSD style accept() API in certain circumstances. Some popular Windows products, typically virus scanning or virtual private network packages, have bugs that interfere with the proper operation of AcceptEx(). If you encounter an error condition like:
[error] (730038)An operation was attempted on something that is not a socket.: winnt_accept: AcceptEx failed. Attempting to recover.
you should use this directive to disable the use of AcceptEx().
Documentation for Apache 2.2.x available @ http://httpd.apache.org/docs/2.2/
Dan Ruth
Try this directive, it seemed to do the trick for us. We were experienceing simliar issues…
MaxRequestsPerChild: Like the Unix directive, this controls how many requests (actually, connections) which a single child process will serve before exiting. However, unlike on Unix, a replacement process is not instantly available. Use the default MaxRequestsPerChild 0, unless instructed to change the behavior to overcome a memory leak in third party modules or in-process applications.
David Westerfield
Thanks for the advice, Dan!