pax_global_header00006660000000000000000000000064142017531610014512gustar00rootroot0000000000000052 comment=20a8d34da93a7e6fb2703177d8c999a48eeea764 golang-github-pbnjay-memory-0.0~git20210728.7b4eea6/000077500000000000000000000000001420175316100215535ustar00rootroot00000000000000golang-github-pbnjay-memory-0.0~git20210728.7b4eea6/LICENSE000066400000000000000000000027461420175316100225710ustar00rootroot00000000000000BSD 3-Clause License Copyright (c) 2017, Jeremy Jay All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. golang-github-pbnjay-memory-0.0~git20210728.7b4eea6/README.md000066400000000000000000000024221420175316100230320ustar00rootroot00000000000000# memory Package `memory` provides two methods reporting total physical system memory accessible to the kernel, and free memory available to the running application. This package has no external dependency besides the standard library and default operating system tools. Documentation: [![GoDoc](https://godoc.org/github.com/pbnjay/memory?status.svg)](https://godoc.org/github.com/pbnjay/memory) This is useful for dynamic code to minimize thrashing and other contention, similar to the stdlib `runtime.NumCPU` See some history of the proposal at https://github.com/golang/go/issues/21816 ## Example ```go fmt.Printf("Total system memory: %d\n", memory.TotalMemory()) fmt.Printf("Free memory: %d\n", memory.FreeMemory()) ``` ## Testing Tested/working on: - macOS 10.12.6 (16G29), 10.15.7 (19H2) - Windows 10 1511 (10586.1045) - Linux RHEL (3.10.0-327.3.1.el7.x86_64) - Raspberry Pi 3 (ARMv8) on Raspbian, ODROID-C1+ (ARMv7) on Ubuntu, C.H.I.P (ARMv7). - Amazon Linux 2 aarch64 (m6a.large, 4.14.203-156.332.amzn2.aarch64) Tested on virtual machines: - Windows 7 SP1 386 - Debian stretch 386 - NetBSD 7.1 amd64 + 386 - OpenBSD 6.1 amd64 + 386 - FreeBSD 11.1 amd64 + 386 - DragonFly BSD 4.8.1 amd64 If you have access to untested systems please test and report success/bugs. golang-github-pbnjay-memory-0.0~git20210728.7b4eea6/doc.go000066400000000000000000000014701420175316100226510ustar00rootroot00000000000000// Package memory provides a single method reporting total system memory // accessible to the kernel. package memory // TotalMemory returns the total accessible system memory in bytes. // // The total accessible memory is installed physical memory size minus reserved // areas for the kernel and hardware, if such reservations are reported by // the operating system. // // If accessible memory size could not be determined, then 0 is returned. func TotalMemory() uint64 { return sysTotalMemory() } // FreeMemory returns the total free system memory in bytes. // // The total free memory is installed physical memory size minus reserved // areas for other applications running on the same system. // // If free memory size could not be determined, then 0 is returned. func FreeMemory() uint64 { return sysFreeMemory() } golang-github-pbnjay-memory-0.0~git20210728.7b4eea6/example_test.go000066400000000000000000000003741420175316100246000ustar00rootroot00000000000000package memory_test import ( "fmt" "github.com/pbnjay/memory" ) func ExampleTotalMemory() { fmt.Printf("Total system memory: %d\n", memory.TotalMemory()) } func ExampleFreeMemory() { fmt.Printf("Free system memory: %d\n", memory.FreeMemory()) } golang-github-pbnjay-memory-0.0~git20210728.7b4eea6/go.mod000066400000000000000000000000511420175316100226550ustar00rootroot00000000000000module github.com/pbnjay/memory go 1.16 golang-github-pbnjay-memory-0.0~git20210728.7b4eea6/memory_bsd.go000066400000000000000000000004341420175316100242430ustar00rootroot00000000000000// +build freebsd openbsd dragonfly netbsd package memory func sysTotalMemory() uint64 { s, err := sysctlUint64("hw.physmem") if err != nil { return 0 } return s } func sysFreeMemory() uint64 { s, err := sysctlUint64("hw.usermem") if err != nil { return 0 } return s } golang-github-pbnjay-memory-0.0~git20210728.7b4eea6/memory_darwin.go000066400000000000000000000017701420175316100247630ustar00rootroot00000000000000// +build darwin package memory import ( "os/exec" "regexp" "strconv" ) func sysTotalMemory() uint64 { s, err := sysctlUint64("hw.memsize") if err != nil { return 0 } return s } func sysFreeMemory() uint64 { cmd := exec.Command("vm_stat") outBytes, err := cmd.Output() if err != nil { return 0 } rePageSize := regexp.MustCompile("page size of ([0-9]*) bytes") reFreePages := regexp.MustCompile("Pages free: *([0-9]*)\\.") // default: page size of 4096 bytes matches := rePageSize.FindSubmatchIndex(outBytes) pageSize := uint64(4096) if len(matches) == 4 { pageSize, err = strconv.ParseUint(string(outBytes[matches[2]:matches[3]]), 10, 64) if err != nil { return 0 } } // ex: Pages free: 1126961. matches = reFreePages.FindSubmatchIndex(outBytes) freePages := uint64(0) if len(matches) == 4 { freePages, err = strconv.ParseUint(string(outBytes[matches[2]:matches[3]]), 10, 64) if err != nil { return 0 } } return freePages * pageSize } golang-github-pbnjay-memory-0.0~git20210728.7b4eea6/memory_linux.go000066400000000000000000000012241420175316100246300ustar00rootroot00000000000000// +build linux package memory import "syscall" func sysTotalMemory() 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. return uint64(in.Totalram) * uint64(in.Unit) } func sysFreeMemory() 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. return uint64(in.Freeram) * uint64(in.Unit) } golang-github-pbnjay-memory-0.0~git20210728.7b4eea6/memory_test.go000066400000000000000000000003031420175316100244450ustar00rootroot00000000000000package memory import "testing" func TestNonZero(t *testing.T) { if TotalMemory() == 0 { t.Fatal("TotalMemory returned 0") } if FreeMemory() == 0 { t.Fatal("FreeMemory returned 0") } } golang-github-pbnjay-memory-0.0~git20210728.7b4eea6/memory_windows.go000066400000000000000000000025101420175316100251620ustar00rootroot00000000000000// +build windows package memory import ( "syscall" "unsafe" ) // omitting a few fields for brevity... // https://msdn.microsoft.com/en-us/library/windows/desktop/aa366589(v=vs.85).aspx type memStatusEx struct { dwLength uint32 dwMemoryLoad uint32 ullTotalPhys uint64 ullAvailPhys uint64 unused [5]uint64 } func sysTotalMemory() uint64 { kernel32, err := syscall.LoadDLL("kernel32.dll") if err != nil { return 0 } // GetPhysicallyInstalledSystemMemory is simpler, but broken on // older versions of windows (and uses this under the hood anyway). globalMemoryStatusEx, err := kernel32.FindProc("GlobalMemoryStatusEx") if err != nil { return 0 } msx := &memStatusEx{ dwLength: 64, } r, _, _ := globalMemoryStatusEx.Call(uintptr(unsafe.Pointer(msx))) if r == 0 { return 0 } return msx.ullTotalPhys } func sysFreeMemory() uint64 { kernel32, err := syscall.LoadDLL("kernel32.dll") if err != nil { return 0 } // GetPhysicallyInstalledSystemMemory is simpler, but broken on // older versions of windows (and uses this under the hood anyway). globalMemoryStatusEx, err := kernel32.FindProc("GlobalMemoryStatusEx") if err != nil { return 0 } msx := &memStatusEx{ dwLength: 64, } r, _, _ := globalMemoryStatusEx.Call(uintptr(unsafe.Pointer(msx))) if r == 0 { return 0 } return msx.ullAvailPhys } golang-github-pbnjay-memory-0.0~git20210728.7b4eea6/memsysctl.go000066400000000000000000000005711420175316100241250ustar00rootroot00000000000000// +build darwin freebsd openbsd dragonfly netbsd package memory import ( "syscall" "unsafe" ) func sysctlUint64(name string) (uint64, error) { s, err := syscall.Sysctl(name) if err != nil { return 0, err } // hack because the string conversion above drops a \0 b := []byte(s) if len(b) < 8 { b = append(b, 0) } return *(*uint64)(unsafe.Pointer(&b[0])), nil } golang-github-pbnjay-memory-0.0~git20210728.7b4eea6/stub.go000066400000000000000000000002551420175316100230610ustar00rootroot00000000000000// +build !linux,!darwin,!windows,!freebsd,!dragonfly,!netbsd,!openbsd package memory func sysTotalMemory() uint64 { return 0 } func sysFreeMemory() uint64 { return 0 }