in patches/gopsutil/v3/mem/mem_linux.go [58:318]
func fillFromMeminfoWithContext() (*VirtualMemoryStat, *VirtualMemoryExStat, error) {
filename := common.HostProc("meminfo")
lines, _ := common.ReadLines(filename)
// flag if MemAvailable is in /proc/meminfo (kernel 3.14+)
memavail := false
activeFile := false // "Active(file)" not available: 2.6.28 / Dec 2008
inactiveFile := false // "Inactive(file)" not available: 2.6.28 / Dec 2008
sReclaimable := false // "Sreclaimable:" not available: 2.6.19 / Nov 2006
ret := &VirtualMemoryStat{}
retEx := &VirtualMemoryExStat{}
for _, line := range lines {
fields := strings.Split(line, ":")
if len(fields) != 2 {
continue
}
key := strings.TrimSpace(fields[0])
value := strings.TrimSpace(fields[1])
value = strings.Replace(value, " kB", "", -1)
switch key {
case "MemTotal":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.Total = t * 1024
case "MemFree":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.Free = t * 1024
case "MemAvailable":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
memavail = true
ret.Available = t * 1024
case "Buffers":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.Buffers = t * 1024
case "Cached":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.Cached = t * 1024
case "Active":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.Active = t * 1024
case "Inactive":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.Inactive = t * 1024
case "Active(anon)":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
retEx.ActiveAnon = t * 1024
case "Inactive(anon)":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
retEx.InactiveAnon = t * 1024
case "Active(file)":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
activeFile = true
retEx.ActiveFile = t * 1024
case "Inactive(file)":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
inactiveFile = true
retEx.InactiveFile = t * 1024
case "Unevictable":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
retEx.Unevictable = t * 1024
case "WriteBack":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.WriteBack = t * 1024
case "WriteBackTmp":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.WriteBackTmp = t * 1024
case "Dirty":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.Dirty = t * 1024
case "Shmem":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.Shared = t * 1024
case "Slab":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.Slab = t * 1024
case "SReclaimable":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
sReclaimable = true
ret.Sreclaimable = t * 1024
case "SUnreclaim":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.Sunreclaim = t * 1024
case "PageTables":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.PageTables = t * 1024
case "SwapCached":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.SwapCached = t * 1024
case "CommitLimit":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.CommitLimit = t * 1024
case "Committed_AS":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.CommittedAS = t * 1024
case "HighTotal":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.HighTotal = t * 1024
case "HighFree":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.HighFree = t * 1024
case "LowTotal":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.LowTotal = t * 1024
case "LowFree":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.LowFree = t * 1024
case "SwapTotal":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.SwapTotal = t * 1024
case "SwapFree":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.SwapFree = t * 1024
case "Mapped":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.Mapped = t * 1024
case "VmallocTotal":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.VmallocTotal = t * 1024
case "VmallocUsed":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.VmallocUsed = t * 1024
case "VmallocChunk":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.VmallocChunk = t * 1024
case "HugePages_Total":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.HugePagesTotal = t
case "HugePages_Free":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.HugePagesFree = t
case "Hugepagesize":
t, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return ret, retEx, err
}
ret.HugePageSize = t * 1024
}
}
ret.Cached += ret.Sreclaimable
if !memavail {
if activeFile && inactiveFile && sReclaimable {
ret.Available = calculateAvailVmem(ret, retEx)
} else {
ret.Available = ret.Cached + ret.Free
}
}
ret.Used = ret.Total - ret.Free - ret.Buffers - ret.Cached
ret.UsedPercent = float64(ret.Used) / float64(ret.Total) * 100.0
return ret, retEx, nil
}