When you wake up in the morning, log into your web server and glimpse at your php error logs it can be a little unsettling to see every page request producing ‘Unable to allocate memory pool’ error messages. After doing some googling and reading the APC bug list I found lots of people are experiencing this problem. I was experiencing this issue myself and needed a solution fast. I scrolled down through the comments and discovered that the general consensus was to set:
apc.mmap_file_mask = /dev/zero
I decided to continue reading up on APC having made this change however a few days later MySQL randomly died. A few days later the same thing happened again. At this point I decided to revisit how I had my memory settings configured on my server. I dropped my kernel.shmmax down to about 25% of my VPS’s total amount of RAM. One thing I hadn’t used or paid much attention to is apc.php which comes with APC. I copied this to somewhere that I could browse to on my web server and looked at the stats of my cache. It became immediately apparent what was occurring – my cache was becoming so fragmented and full of stale data that there was nowhere that the cache could use.
That’s when I decided to read about the various TTL settings for APC.
The number of seconds a cache entry is allowed to idle in a slot in case this cache entry slot is needed by another entry. Leaving this at zero means that APC's cache could potentially fill up with stale entries while newer entries won't be cached. In the event of a cache running out of available memory, the cache will be completely expunged if ttl is equal to 0. Otherwise, if the ttl is greater than 0, APC will attempt to remove expired entries.
I then looked at Rasmus’s example of php.net and looked at his APC settings. I noticed he had apc.ttl = 0 and that apc.user_ttl = 600 and apc.gc_ttl = 600. I made those changes to my own configuration and haven’t had an issue since. The site is significantly faster than it was with apc.ttl set to a fixed amount and I’d rather the cache flushed itself and started rebuilding itself rather than have the cost of defragmenting the cache each page request. I’m no authority on the matter but I know what worked for me.
I’ve since changed my apc.mmap_file_mask back to:
apc.mmap_file_mask = /tmp/apc.XXXXXX
and am monitoring how my server runs. If I have any updates I’ll let you all know.
Edit: I’ve been running with this config setup for 9 months or so now and it is running like a dream. I highly recommend having apc.ttl = 0, you can set your apc.user_ttl to whatever is appropriate for your caching setup and apc.mmap_file_mask = /tmp/apc.XXXXXX