...
1
2
3 package mem
4
5 import (
6 "context"
7 "os/exec"
8 "strconv"
9 "strings"
10
11 "golang.org/x/sys/unix"
12 )
13
14
15 func getVMStat(vms *VirtualMemoryStat) error {
16 vm_stat, err := exec.LookPath("vm_stat")
17 if err != nil {
18 return err
19 }
20 out, err := invoke.Command(vm_stat)
21 if err != nil {
22 return err
23 }
24 return parseVMStat(string(out), vms)
25 }
26
27 func parseVMStat(out string, vms *VirtualMemoryStat) error {
28 var err error
29
30 lines := strings.Split(out, "\n")
31 pagesize := uint64(unix.Getpagesize())
32 for _, line := range lines {
33 fields := strings.Split(line, ":")
34 if len(fields) < 2 {
35 continue
36 }
37 key := strings.TrimSpace(fields[0])
38 value := strings.Trim(fields[1], " .")
39 switch key {
40 case "Pages free":
41 free, e := strconv.ParseUint(value, 10, 64)
42 if e != nil {
43 err = e
44 }
45 vms.Free = free * pagesize
46 case "Pages inactive":
47 inactive, e := strconv.ParseUint(value, 10, 64)
48 if e != nil {
49 err = e
50 }
51 vms.Inactive = inactive * pagesize
52 case "Pages active":
53 active, e := strconv.ParseUint(value, 10, 64)
54 if e != nil {
55 err = e
56 }
57 vms.Active = active * pagesize
58 case "Pages wired down":
59 wired, e := strconv.ParseUint(value, 10, 64)
60 if e != nil {
61 err = e
62 }
63 vms.Wired = wired * pagesize
64 }
65 }
66 return err
67 }
68
69
70 func VirtualMemory() (*VirtualMemoryStat, error) {
71 return VirtualMemoryWithContext(context.Background())
72 }
73
74 func VirtualMemoryWithContext(ctx context.Context) (*VirtualMemoryStat, error) {
75 ret := &VirtualMemoryStat{}
76
77 total, err := getHwMemsize()
78 if err != nil {
79 return nil, err
80 }
81 err = getVMStat(ret)
82 if err != nil {
83 return nil, err
84 }
85
86 ret.Available = ret.Free + ret.Inactive
87 ret.Total = total
88
89 ret.Used = ret.Total - ret.Available
90 ret.UsedPercent = 100 * float64(ret.Used) / float64(ret.Total)
91
92 return ret, nil
93 }
94
View as plain text