note: copied from SuperUser:
For older versions of OSX, see this thread on forums.macosxhints.com.
Credit goes to dblu for explaining the use of plutil
, ZILjr for introducing the wait4path
command, and ekl for simplifying the whole thing by eliminating the need for an intermediate shell script.
Complete solution:
1. Open Terminal and make a backup copy of Apple's default dynamic_pager.plist:
$ cd /System/Library/LaunchDaemons
$ sudo cp com.apple.dynamic_pager.plist{,_bak}
2. Convert the plist from binary to plain XML:
$ sudo plutil -convert xml1 com.apple.dynamic_pager.plist
3. Open the converted plist with your text editor of choice. (I use pico
, see dblu's answer for an example using vim
):
$ sudo pico -w com.apple.dynamic_pager.plist
It should look as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs$
<plist version="1.0">
<dict>
<key>EnableTransactions</key>
<true/>
<key>HopefullyExitsLast</key>
<true/>
<key>Label</key>
<string>com.apple.dynamic_pager</string>
<key>OnDemand</key>
<false/>
<key>ProgramArguments</key>
<array>
<string>/sbin/dynamic_pager</string>
<string>-F</string>
<string>/private/var/vm/swapfile</string>
</array>
</dict>
</plist>
4. Modify the ProgramArguments array (lines 13 through 18) to use the wait4path
shell command prior to launching dynamic_pager. See note #1 for details on why this is necessary. In the following example, my partition is called Swap
, and I chose to put the swapfiles in a hidden directory on that partition, called .vm
be sure that the directory you specify actually exists. The XML should look as follows:
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>-c</string>
<string>/bin/wait4path /Volumes/Swap/ &&
/sbin/dynamic_pager -F /Volumes/Swap/.vm/swapfile</string>
</array>
5. Save the plist, and return to the terminal prompt. Using pico
, the commands would be:
<ctrl+o> to save the file
<enter> to accept the same filename (com.apple.dynamic_pager.plist)
<ctrl+x> to exit
6. Convert the modified plist back to binary:
$ sudo plutil -convert binary1 com.apple.dynamic_pager.plist
7. Restart your Mac. If you run into trouble, switch to verbose startup mode by holding down Command-v immediately after the startup chime. This will let you see all of the startup messages that appear during startup. If you run into even worse trouble (i.e. you never see the login screen), hold down Command-s instead. This will boot the computer in single-user mode (no graphical UI, just a command prompt) and allow you to restore the backup copy of com.apple.dynamic_pager.plist that you made in step 1.
8. Once the computer boots, fire up Terminal and verify that the swap files have actually been moved:
$ cd /Volumes/Swap/.vm
$ ls -l
You should see something like this:
-rw------- 1 someUser staff 67108864 18 Sep 12:02 swapfile0
9. Delete the old swapfiles:
$ cd /private/var/vm
$ sudo rm swapfile*
10. Profit!
Note 1
Modifying the arguments to dynamic_pager in the plist without using wait4path
does not always work, and when it fails, it does so in a spectacularly silent way. The problem stems from the fact that dynamic_pager is launched very early in the startup process. If your swap partition has not yet been mounted when dynamic_pager is first loaded (in my experience, this happens 99% of the time), then the system will fake its way through. It will create a symbolic link in your /Volumes directory which has the same name as your swap partition, but points back to the default swapfile location (/private/var/vm). Then, when your actual swap partition mounts, it will be given the name Swap 1
(or YourDriveName 1
). You can see the problem by opening up Terminal and listing the contents of your /Volumes directory:
$ cd /Volumes
$ ls -l
You will see something like this:
drwxrwxrwx 11 yourUser staff 442 16 Sep 12:13 Swap -> private/var/vm
drwxrwxrwx 14 yourUser staff 5 16 Sep 12:13 Swap 1
lrwxr-xr-x 1 root admin 1 17 Sep 12:01 System -> /
Note that this failure can be very hard to spot. If you were to check for the swapfiles as I show in step 12, you would still see them! The symbolic link would make it seem as though your swapfiles had been moved, even though they were actually being stored in the default location.
Note 2
I was originally unable to get this to work in Snow Leopard because com.apple.dynamic_pager.plist was stored in binary format. I made a copy of the original file and opened it with Apple's Property List Editor (available with Xcode) in order to make changes, but this process added some extended attributes to the plist file which caused the system to ignore it and just use the defaults. As dblu pointed out, using plutil
to convert the file to plain XML works like a charm.
Note 3
You can check the Console application to see any messages that dynamic_pager_init echos to the screen. If you see the following lines repeated over and over again, there is a problem with the setup. I ran into these messages because I forgot to create the '.vm' directory that I specified in dynamic_pager_init.
com.apple.launchd[1] (com.apple.dynamic_pager[176]) Exited with exit code: 1
com.apple.launchd[1] (com.apple.dynamic_pager) Throttling respawn: Will start in 10 seconds
When everything is working properly, you may see the above message a couple of times only, and then no more of the "Throttling respawn" messages. This means that the system did have to wait for the partition to load, but in the end it was successful.
Exclude the path from Time Machine
In OS X 10.7 and later you can do this with tmutil. Example:
sudo tmutil addexclusion -p /Volumes/Swap/.vm
For that example, to review the result:
tmutil isexcluded /Volumes/Swap && tmutil isexcluded /Volumes/Swap/.vm
If the volume used for swap need not be indexed
Use mdutil. Example, to switch off then erase the store:
sudo mdutil -i off /Volumes/Swap && sudo mdutil -E /Volumes/Swap
… set the minimum swapfile size …
dynamic_pager(8) Mac OS X Manual Page
With Terminal, a one-off command to convert a property list to a format that will be easily editable:
sudo plutil -convert xml1 com.apple.dynamic_pager.plist
Then if you're happy to edit with nano:
sudo nano /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist
Use option -S
to set a size in bytes, then save that property list and either:
- simply, safely, restart the Mac; or
- unload then load the daemon – but that may be risky (and I suspect that only a restart of the Mac will reap the potential benefits).
That's a single size for all files, and any use of option -S
will cause dynamic_pager
to not use variable sized paging files:
- we can not simply set a minimum – alone – amongst that set of variables.
… I want default allocate minimum 4GB …
Based on my tests with Mountain Lion, you might find that dynamic_pager
will quietly fail to begin with a file that is so large.
Proceed with caution – pay attention to the actual size of swapfile0
and if it is zero bytes, then beware of inexplicable reductions to free space on the volume where the files are expected.
… at releasing will never release under 4GB size. …
Consider dynamic_pager
option -L
If there are more than low-water-trigger bytes free in the external paging files, the kernel will coalese in-use pages and signal dynamic_pager to discard an external paging file. Low-water-trigger must be greater than high-water-trigger + filesize.
Best Answer
First - yes, the OS in general will use RAM before swap. There's no loss of computational power involved in that.
You seem to have jumped to the conclusion that macOS is using swap, when it could as well be using free memory based on the htop screenshot. You cannot make that conclusion from a simple sample of the memory usage.
In reality, you could have been running programs that were using a lot of RAM forcing macOS to swap memory to disk. Then you quit some of those programs (or they deallocated a chunk of RAM). Then if you take a htop sample now, you'll see that RAM usage is low (lots of free RAM), but you're also using lots of swap.
But that is not a problem - in fact it is intended to be this way! It wouldn't be wise for macOS to start swapping in those pages that have been placed on disk. It will do this when they're required (i.e. used by programs), but until that happens, it could be that those pages would never be used - and thus time spent swapping them in will be lost.
You write that in comparison to your Ubuntu PC you observe a different behaviour. You should know that you can actually change that behaviour. On Linux you can use sysctl to set the vm.swappiness variable. It will change how aggressive the OS is in swapping things out to disk.
You also ask why your macOS system does not use fixed size swap as Ubuntu does. In fact, Ubuntu also supports dynamic sized swap using the "swapspace" command. You can set minimum and maximum sizes, and it will dynamically add/remove swap space as needs change.