Skip to content

Linux/WSL2: false OOM due to using Freeram instead of MemAvailable #3

@GavinPalmer1984

Description

@GavinPalmer1984

Bug

mmap/sysinfo_unix.go uses syscall.Sysinfo_t.Freeram to determine available memory. On Linux (and especially WSL2), Freeram maps to MemFree from /proc/meminfo, which is almost always near zero because the kernel aggressively uses free RAM for page cache.

The correct value to use is MemAvailable from /proc/meminfo, which accounts for reclaimable page cache and buffers.

Reproduction

On a system with 18GB total / 9.3GB available:

$ dlgo run tinyllama-1.1b-chat-v1.0.Q4_0.gguf
Error: insufficient memory: runtime buffers need ~0.0 GB even at minimum context (64 tokens)
but only 0.0 GB available (17.6 GB total, 0.3 GB free).
Close other applications to free RAM
$ grep -E 'MemFree|MemAvailable' /proc/meminfo
MemFree:          290496 kB
MemAvailable:    9381480 kB

Suggested Fix

In mmap/sysinfo_unix.go, read MemAvailable from /proc/meminfo instead of using si.Freeram:

func GetSystemMemInfo() (SystemMemInfo, error) {
    var si syscall.Sysinfo_t
    if err := syscall.Sysinfo(&si); err != nil {
        return SystemMemInfo{}, err
    }
    unit := uint64(si.Unit)
    total := uint64(si.Totalram) * unit
    avail := uint64(si.Freeram) * unit

    // Prefer MemAvailable from /proc/meminfo — Freeram excludes
    // reclaimable page cache, causing false OOM on Linux/WSL2.
    if f, err := os.Open("/proc/meminfo"); err == nil {
        defer f.Close()
        sc := bufio.NewScanner(f)
        for sc.Scan() {
            if strings.HasPrefix(sc.Text(), "MemAvailable:") {
                fields := strings.Fields(sc.Text())
                if len(fields) >= 2 {
                    if kb, err := strconv.ParseUint(fields[1], 10, 64); err == nil {
                        avail = kb * 1024
                    }
                }
                break
            }
        }
    }

    return SystemMemInfo{
        TotalPhysical:     total,
        AvailablePhysical: avail,
    }, nil
}

Environment

  • Linux 6.6.87 (WSL2)
  • Go 1.26.0
  • 18GB RAM, i7-8700K

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions