Is there any way to automatically prevent running out of memory?

Solution 1:

Monit can do this.

You could use a config line such as:

 check process apache 
    with pidfile "/var/lock/apache/httpd.pid"
    start program = "/etc/init.d/httpd start" with timeout 60 seconds
    stop program = "/etc/init.d/httpd stop"
    if 2 restarts within 3 cycles then timeout
    if totalmem > 100 Mb for 5 cycles then restart
    if children > 255 for 5 cycles then stop
    if cpu usage > 95% for 3 cycles then restart
    if failed port 80 protocol http then restart
    group server
    depends on httpd.conf, httpd.bin

(Modified from this config example on monit.com)

This could play into the ulimit option mentioned earlier as well.

Restarting the service is a bandaid. You should instead try to find out why it's leaking memory.

Solution 2:

Apache shouldn't be running out of memory, unless you have some memory leak in the application you run under apache, or if a certain request makes a huge demand on memory. I would investigate why I run out of memory in the first place, than implementing a brute force solution like one you ask for.

With above said, it should be very straightforward to implement a basic cron job script, which just calls "ps" on apache processes, finds out how much memory they consume, and restart if needed. Running this every minute should be enough.

But again - this is not a good approach.

Solution 3:

Running apache under ulimit -m X will cause it to get killed when it (and its children) exceed XK RSS. I don't know if Ubuntu still uses Upstart but if it does then you can add the respawn option to the apache upstart config file to cause it to be restarted automatically after it is killed.