Macos – How to disable Mac OS X from using swap when there still is “Inactive” memory

macosmemorymemory managementosx-snow-leopardswap

A common phenomena in my day to day usage (and several other's according to various posts throughout the internet) of OS X, the system seems to become slow whenever there is no more "Free" memory available. Supposedly, this is due to swapping, since heavy disk activity is apparent and that vm_stat reports many pageouts. (Correct me from wrong)

However, the amount of "Inactive" ram is typically around 12.5%-25% of all available memory (^1.) when swapping starts/occurs/ends.

According to :

Inactive memory

This information in memory is not actively being used, but was
recently used.

For example, if you've been using Mail and then quit it, the RAM that
Mail was using is marked as Inactive memory. This Inactive memory is
available for use by another application, just like Free memory.
However, if you open Mail before its Inactive memory is used by a
different application, Mail will open quicker because its Inactive
memory is converted to Active memory, instead of loading Mail from the
slower hard disk.

And according to :

The inactive list contains pages that are currently resident in
physical memory but have not been accessed recently. These pages
contain valid data but may be released from memory at any time.

So, basically: When a program has quit, it's memory becomes marked as Inactive and should be claimable at any time. Still, OS X will prefer to start swapping out memory to the Swap file instead of just claiming this memory, whenever the "Free" memory gets to low.

Why? What is the advantage of this behavior over, say, instantly releasing Inactive memory and not even touch the swap file? Some sources (^2.) indicate that OS X would page out the "Inactive" memory to swap before releasing it, but that doesn't make sense now does it if the memory may be released from memory at any time? Swapping is expensive, releasing is cheap, right?

Can this behavior be changed using some preference or known hack? (Preferably one that doesn't include disabling swap/dynamic_pager altogether and restarting…)

I do appreciate the purge command, as well as the concept of Repairing disk permissions to force some Free memory, but those are ways to painfully force more Free memory than to actually fixing the swap/release decision logic…

Btw a similar question was asked here: and here: but even though the OPs re-asked the core question, none of the replies addresses an answer to it…

^1. UPDATE 17-mar-2012 Since I first posted this question, I have gone from 4gb to 8gb of installed ram, and the problem remains. The amount of "Inactive" ram was 0.5gb-1.0gb before and is now typically around 1.0-2.0GB when swapping starts/occurs/ends, ie it seems that around 12.5%-25% of the ram is preserved as Inactive by osx kernel logic.

^2. For instance :

Once all your memory is used (free memory is 0), the OS will write out
inactive memory to the swapfile to make more room in active memory.

UPDATE 17-mar-2012

Here is a round-up of the methods that have been suggested to help so far:

The purge command

"Used to approximate initial boot conditions with a cold disk buffer cache for performance analysis. It does not affect anonymous memory that has been allocated through malloc, vm_allocate, etc".

This is useful to prevent osx to swap-out the disk cache (which is ridiculous that osx actually does so in the first place), but with the downside that the disk cache is released, meaning that if the disk cache was not about to be swapped out, one would simply end up with a cold disk buffer cache, probably affecting performance negatively.

The FreeMemory app and/or Repairing disk permissions to force some Free memory

Doesn't help releasing any memory, only moving some gigabytes of memory contents from ram to the hd. In the end, this causes lots of swap-ins when I attempt to use the applications that were open while freeing memory, as a lot of its vm is now on swap.

Speeding up swap-allocation using dynamicpagerwrapper

Seems a good thing to do in order to speed up swap-usage, but does not address the problem of osx swapping in the first place while there is still inactive memory.

Disabling swap by disabling dynamicpager and restarting

This will force osx not to use swap to the price of the system hanging when all memory is used. Not a viable alternative…

Disabling swap using a hacked dynamicpager

Similar to disabling dynamicpager above, some excerpts from the comments to the blog post indicate that this is not a viable solution: "The Inactive Memory is high as usual". "when your system is running out of memory, the whole os hangs…", "if you consume the whole amount of memory of the mac, the machine will likely hang"

To sum up, I am still unaware of a way of disabling Mac OS X from using swap when there still is "Inactive" memory. If it isn't possible, maybe at least there is an explanation somewhere of why osx prefers to swap out memory that may be released from memory at any time?

Best Answer

By definition, inactive memory is memory that is ready to be paged out, and paging it out might involve writing it to swap. This is not any kind of problem or issue that should be optimized; it is in fact OS X working as designed.

Unfortunately, tech support writers are not kernel developers, and the Apple Knowledge Base support article quote is just wrong when it claims that Inactive memory is memory unused by programs. When you quit a program, all of its resident memory becomes Free; it doesn't stop over in Inactive. However, the second link to the developer site describing how memory management works is a good resource, if read fully.

There are many misconceptions about what "inactive memory" means in OS X. Contrary to the misconceptions, not all inactive memory is empty, unused, cache, or purgeable. In fact, Active memory can be cached or purgeable as well, if it has been recently accessed. Much inactive memory also contains data that cannot be simply discarded. If it were discarded, programs would crash, because the discarded pages would have contained valid data (as the quote from the OS X developer's side says,) and programs expect data they have stored in (virtual) memory to not just disappear.

Inactive memory contains the same types of data as active memory. The only difference is that OS X has noticed that some chunks of memory have not been read from or written to in a while.

The reason that OS X classifies some memory as inactive and other regions as "active" has to do with paging out. When memory runs low, you are going to have to page out some data. The question is, which data? If you page out data that a program turns out to immediately need again, it wastes time and accomplishes nothing. So you want to page out memory that a program won't immediately need to use again.

Anticipating which pages are likely to be unneeded in the future is difficult because a program can use its virtual memory however it likes and not tell the OS anything about what its plans are. But as a heuristic, most programs are "sticky" in their memory usage; if they haven't used some piece of memory in a while they are likely to continue not using that memory, and likely to continue using memory that they have recently used.

So when the OS decides to page out some data, it takes the strategy of swapping pages that haven't been used recently. This is why OS X sorts the memory that is being occupied by programs into two piles of "active" and "inactive." The above posted link to the Developer site, if read fully, tells how that process happens:

  • When memory starts getting low, the OS starts going through the active memory pages, and sets a flag on each.
  • If a program reads or writes to a page, the flag is cleared.
  • If, after some delay, the flag is not cleared, that page gets sorted into the "inactive" pile.
  • If an "inactive" page is accessed by its program, it is put back into the "active" pile.
  • When memory runs out, the "inactive" pages are paged out.

Note that this sorting process to decide which memory to swap out is similar across all modern operating systems. Linux has the same two lists of active and inactive pages, as described in Understanding the Linux Virtual Memory Manager. Windows might use something a bit different with more than two classes of recency; I can't find a recent, reliable technical description at the moment. More implementations are discussed at the Wikipedia page entitled "Page replacement algorithm". The only difference with OS X was how the statistics were shown: someone decided it would be a good idea to show separate numbers for active and inactive in top or Activity monitor. In retrospect this was probably not such a good idea (and this has changed in OS X 10.9.)

This process of setting and clearing flags and maintaining active/inactive heaps does take a little bit of processor power. For that reason, OS X doesn't do it when there is a lot of free memory. So the first programs you start up will show up as all "active" memory until free memory starts running low.

So, as you start from a blank slate, and open more and more programs, you can expect to see the following progression in Activity Monitor:

  • First, there is a lot of "free" memory and very little inactive. This is because the memory flagger hasn't started running.
  • As the amount of free memory drops, OS X will start running its memory flagger, and you will start to see the amount of "inactive" rising. Each bit of "inactive" was previously "active."
  • When you run out of free memory, pages from the "inactive" pile will be paged out. The memory-flagger will also be running full tilt sorting out memory into active and inactive. Typically, you will see a lot of "inactive" while swap is being written to, indicating that the memory-flagger is doing what it is supposed to.

Pages must be classified as inactive before they are swapped out. That is what the quote from the Apple Developer site means when it says "These pages contain valid data but may be released from memory at any time." This is in opposition to Active pages, which will not be released until after they have been demoted to Inactive. There are various ways of releasing pages; if the page was mapped from a file and has not been modified, it can be deleted immediately and re-read on demand. Similarly if it is memory that had been previously swapped out and not modified since it was swapped in. Programs can also explicitly allocate cache and purgeable memory, to store data that can be forgotten and recreated on demand (but the reason a program would allocate cache is if it takes significant time to recreate that data.) But much of inactive memory is memory that programs have written valid data to, and paging out this data requires writing to swap.

Therefore looking at the amount of "inactive" memory in Activity Monitor, and seeing that there is a lot of inactive at the same time as the computer is writing to swap, only tells you that the system is working as designed.

There is also a confusion between inactive memory and file cache. I'm not sure why there is that confusion, because Activity Monitor already lists them under separate headings. Cache is memory used to store recent data that have been read to or written from the file system, in case they need to be accessed again. When memory is low, OS X does tend to get rid of the the cache first. If you have swap thrashing, and Activity monitor shows a big pile of cache (NOT inactive) then that would be a problem. But inactive memory is a different thing.

If in doubt, ignore the distinction between "inactive" and "active." Regard them as being one lump of "memory used by programs" and add the two numbers together. This is what every other operating system does when telling you about memory usage.

NOTE for OS X 10.9: Mavericks introduced "memory compression" which is, more or less, another layer of swap. Active pages now get classified inactive, then compressed (which might show up as Kernel memory depending on what tools you are using,) then written to swap as memory usage increases. Mavericks has also has stopped showing separate numbers for active and inactive in Activity Monitor, since it turns out not to be a useful thing to look at, especially given the misconceptions surrounding it.