macOS High Sierra – Fix Swap File Not Being Created

hanghigh sierravirtual-memory

I recently started running into a lot of memory issues on my mac running High Sierra. Rather than the force quit window coming up, my system would freeze completely and the only way to recover is to force a reboot.

After some investigating, I found out that my system is not creating any swap files even when the memory pressure is critical. There is nothing in the /private/var/vm/ directory.

I have already tried sudo launchctl load -wF /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist.

Is there any other way to enable swapping? Or to run some diagnostics?

Additional details:

I am booting from an external Thunderbolt SSD (I don't know if this is the cause).

Below is the output from vm_stat. If I do anything memory intensive at this stage, my system will freeze.

Mach Virtual Memory Statistics: (page size of 4096 bytes)
Pages free:                                4116.
Pages active:                            854231.
Pages inactive:                          825841.
Pages speculative:                        27754.
Pages throttled:                              0.
Pages wired down:                        606483.
Pages purgeable:                          22070.
“Translation faults”:                  75731290.
Pages copy-on-write:                     401121.
Pages zero filled:                     49766457.
Pages reactivated:                     17690835.
Pages purged:                           1577284.
File-backed pages:                       503400.
Anonymous pages:                        1204426.
Pages stored in compressor:             6563399.
Pages occupied by compressor:           1875311.
Decompressions:                        21012443.
Compressions:                          32102441.
Pageins:                                2172708.
Pageouts:                                 35123.
Swapins:                                      0.
Swapouts:                                     0.

Edit:

Some more details:

This is the output from diskutil ap list

APFS Container (1 found)
|
+-- Container disk4 6BE5FDB5-A68F-4CBF-A404-68AE73E61C10
    ====================================================
    APFS Container Reference:     disk4
    Capacity Ceiling (Size):      499898105856 B (499.9 GB)
    Capacity In Use By Volumes:   452259872768 B (452.3 GB) (90.5% used)
    Capacity Available:           47638233088 B (47.6 GB) (9.5% free)
    |
    +-< Physical Store disk3s2 39853349-6B62-4961-99DE-811BA56465EC
    |   -----------------------------------------------------------
    |   APFS Physical Store Disk:   disk3s2
    |   Size:                       499898105856 B (499.9 GB)
    |
    +-> Volume disk4s1 99688E85-E9EF-3688-A324-913D00FF6A0E
    |   ---------------------------------------------------
    |   APFS Volume Disk (Role):   disk4s1 (No specific role)
    |   Name:                      System (Case-insensitive)
    |   Mount Point:               /
    |   Capacity Consumed:         449420767232 B (449.4 GB)
    |   FileVault:                 No
    |
    +-> Volume disk4s2 729366E4-48AA-45A3-95DA-8871B8A29778
    |   ---------------------------------------------------
    |   APFS Volume Disk (Role):   disk4s2 (Preboot)
    |   Name:                      Preboot (Case-insensitive)
    |   Mount Point:               Not Mounted
    |   Capacity Consumed:         20357120 B (20.4 MB)
    |   FileVault:                 No
    |
    +-> Volume disk4s3 431C0191-2B1F-480C-94D0-AF4748E6D213
    |   ---------------------------------------------------
    |   APFS Volume Disk (Role):   disk4s3 (Recovery)
    |   Name:                      Recovery (Case-insensitive)
    |   Mount Point:               Not Mounted
    |   Capacity Consumed:         509820928 B (509.8 MB)
    |   FileVault:                 No
    |
    +-> Volume disk4s4 5DE0EA6B-CA57-4226-B038-2E256FCC5B98
        ---------------------------------------------------
        APFS Volume Disk (Role):   disk4s4 (VM)
        Name:                      VM (Case-insensitive)
        Mount Point:               Not Mounted
        Capacity Consumed:         2147504128 B (2.1 GB)
        FileVault:                 No

And the output from mount:

/dev/disk4s1 on / (apfs, local, journaled)
devfs on /dev (devfs, local, nobrowse)
/dev/disk2 on /Volumes/Storage (hfs, local, journaled)
map -hosts on /net (autofs, nosuid, automounted, nobrowse)
map auto_home on /home (autofs, automounted, nobrowse)

Solution (Updated):
A number of good solutions suggested. After revisiting the issue again, I would recommend lint's solution below. It's the most general way that accounts for changes in volume names.

Best Answer

I have had the same problem running High Sierra (and Mojave since) off an external SSD. I haven't tried Glorfindel♦'s suggestion to wipe the disk to Sierra on HFS+ before restoring to High Sierra, which seems like a lot of work.

I have, however, been using my own launch daemon with a bash script since January, similar to chrisgooley's solution, however, my script also checks which volume ID to mount. I thought I'd share my solution with the dynamic check for the correct volume ID.

Initially, I hardcoded the volume ID as well but this was problematic because whenever the system booted with additional drives attached, the volume ID would change the swap volume would fail to mount.

My script and daemon are below:

mountvm.sh

#!/bin/bash
# Mount the APFS VM volume if it isn't already mounted

VM_VOLUME=$(/usr/sbin/diskutil list | grep "VM" | awk '{ print $7 }') 
# echo "VM Volume is $VM_VOLUME"
for i in {1..5}
do
    if [ ! -e /private/var/vm/sleepimage ]
    then
#       echo "$(date "+%a %d/%m/%Y %I:%M:%S%p") > VM volume not yet mounted..."
#       echo -n "$(date "+%a %d/%m/%Y %I:%M:%S%p") > "
        /usr/sbin/diskutil mount -mountPoint /private/var/vm/ $VM_VOLUME
        break
    else
#       echo "$(date "+%a %d/%m/%Y %I:%M:%S%p") > VM volume already mounted..."
        if [ $i -lt 6 ]
        then
#           echo -n "$(date "+%a %d/%m/%Y %I:%M:%S%p") > Confirming in "
            for count in {2..1}
            do
#               echo -n "$count min..."
                sleep 60
            done
            echo
        fi
    fi
done

exit 0

com.local.mountvm.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.local.mountvm</string>
    <key>ProgramArguments</key>
    <array>
        <string>[/path/to/script]/mountvm.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

Some notes:

Change the [/path/to/script] in the plist to where ever you place the bash script.

Remove the # on the echo lines in the bash script to troubleshoot (you'll need to run the script in Terminal with sudo or specify a stdout path in the plist).

The script checks whether /private/var/vm/sleepimage exists. If it doesn't, then the swap volume isn't mounted and tries to mount the correct volume. If it does, it will check again four more times in two minute intervals before exiting. The reason I added this was because I found if I simply tried to mount the volume as soon the daemon loaded, it would fail.