Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,13 @@ func TotalMemory() uint64 {
func FreeMemory() uint64 {
return sysFreeMemory()
}

// AvailableMemory returns the total free+freeable system memory in bytes.
//
// The total available memory is the free memory + freeable memory
// such as buffer and cache.
//
// If available memory size could not be determined, then 0 is returned.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"If freeable memory size could not be determined, then freeable memory is assumed to be 0"

Seems to fit the semantics of the windows/bsd/darwin stubs a bit better.

func AvailableMemory() uint64 {
return sysAvailableMemory()
}
5 changes: 5 additions & 0 deletions memory_bsd.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build freebsd || openbsd || dragonfly || netbsd
// +build freebsd openbsd dragonfly netbsd

package memory
Expand All @@ -17,3 +18,7 @@ func sysFreeMemory() uint64 {
}
return s
}

func sysAvailableMemory() uint64 {
return sysFreeMemory()
}
5 changes: 5 additions & 0 deletions memory_darwin.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build darwin
// +build darwin

package memory
Expand Down Expand Up @@ -47,3 +48,7 @@ func sysFreeMemory() uint64 {
}
return freePages * pageSize
}

func sysAvailableMemory() uint64 {
return sysFreeMemory()
}
16 changes: 16 additions & 0 deletions memory_linux.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build linux
// +build linux

package memory
Expand Down Expand Up @@ -27,3 +28,18 @@ func sysFreeMemory() uint64 {
// So we always convert to uint64 to match signature.
return uint64(in.Freeram) * uint64(in.Unit)
}

func sysAvailableMemory() uint64 {
in := &syscall.Sysinfo_t{}
err := syscall.Sysinfo(in)
if err != nil {
return 0
}
// If this is a 32-bit system, then these fields are
// uint32 instead of uint64.
// So we always convert to uint64 to match signature.
// Buffer/cache ram is included on linux since the kernel
// will free this memory for applications if needed, and tends
// to use almost all free memory for itself when it can.
return (uint64(in.Freeram) + uint64(in.Bufferram)) * uint64(in.Unit)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Linux it's generally better to use MemAvailable from /proc/meminfo. There is a good justification for this in the Linux kernel git commit.

The hard part is there's no simple stdlib syscall that I am aware of that can read this. 🙁

}
5 changes: 5 additions & 0 deletions memory_windows.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build windows
// +build windows

package memory
Expand Down Expand Up @@ -58,3 +59,7 @@ func sysFreeMemory() uint64 {
}
return msx.ullAvailPhys
}

func sysAvailableMemory() uint64 {
return sysFreeMemory()
}