meminfo.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. // Copyright 2019 The Prometheus Authors
  2. // Licensed under the Apache License, Version 2.0 (the "License");
  3. // you may not use this file except in compliance with the License.
  4. // You may obtain a copy of the License at
  5. //
  6. // http://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. package procfs
  14. import (
  15. "bufio"
  16. "bytes"
  17. "fmt"
  18. "io"
  19. "strconv"
  20. "strings"
  21. "github.com/prometheus/procfs/internal/util"
  22. )
  23. // Meminfo represents memory statistics.
  24. type Meminfo struct {
  25. // Total usable ram (i.e. physical ram minus a few reserved
  26. // bits and the kernel binary code)
  27. MemTotal uint64
  28. // The sum of LowFree+HighFree
  29. MemFree uint64
  30. // An estimate of how much memory is available for starting
  31. // new applications, without swapping. Calculated from
  32. // MemFree, SReclaimable, the size of the file LRU lists, and
  33. // the low watermarks in each zone. The estimate takes into
  34. // account that the system needs some page cache to function
  35. // well, and that not all reclaimable slab will be
  36. // reclaimable, due to items being in use. The impact of those
  37. // factors will vary from system to system.
  38. MemAvailable uint64
  39. // Relatively temporary storage for raw disk blocks shouldn't
  40. // get tremendously large (20MB or so)
  41. Buffers uint64
  42. Cached uint64
  43. // Memory that once was swapped out, is swapped back in but
  44. // still also is in the swapfile (if memory is needed it
  45. // doesn't need to be swapped out AGAIN because it is already
  46. // in the swapfile. This saves I/O)
  47. SwapCached uint64
  48. // Memory that has been used more recently and usually not
  49. // reclaimed unless absolutely necessary.
  50. Active uint64
  51. // Memory which has been less recently used. It is more
  52. // eligible to be reclaimed for other purposes
  53. Inactive uint64
  54. ActiveAnon uint64
  55. InactiveAnon uint64
  56. ActiveFile uint64
  57. InactiveFile uint64
  58. Unevictable uint64
  59. Mlocked uint64
  60. // total amount of swap space available
  61. SwapTotal uint64
  62. // Memory which has been evicted from RAM, and is temporarily
  63. // on the disk
  64. SwapFree uint64
  65. // Memory which is waiting to get written back to the disk
  66. Dirty uint64
  67. // Memory which is actively being written back to the disk
  68. Writeback uint64
  69. // Non-file backed pages mapped into userspace page tables
  70. AnonPages uint64
  71. // files which have been mapped, such as libraries
  72. Mapped uint64
  73. Shmem uint64
  74. // in-kernel data structures cache
  75. Slab uint64
  76. // Part of Slab, that might be reclaimed, such as caches
  77. SReclaimable uint64
  78. // Part of Slab, that cannot be reclaimed on memory pressure
  79. SUnreclaim uint64
  80. KernelStack uint64
  81. // amount of memory dedicated to the lowest level of page
  82. // tables.
  83. PageTables uint64
  84. // NFS pages sent to the server, but not yet committed to
  85. // stable storage
  86. NFSUnstable uint64
  87. // Memory used for block device "bounce buffers"
  88. Bounce uint64
  89. // Memory used by FUSE for temporary writeback buffers
  90. WritebackTmp uint64
  91. // Based on the overcommit ratio ('vm.overcommit_ratio'),
  92. // this is the total amount of memory currently available to
  93. // be allocated on the system. This limit is only adhered to
  94. // if strict overcommit accounting is enabled (mode 2 in
  95. // 'vm.overcommit_memory').
  96. // The CommitLimit is calculated with the following formula:
  97. // CommitLimit = ([total RAM pages] - [total huge TLB pages]) *
  98. // overcommit_ratio / 100 + [total swap pages]
  99. // For example, on a system with 1G of physical RAM and 7G
  100. // of swap with a `vm.overcommit_ratio` of 30 it would
  101. // yield a CommitLimit of 7.3G.
  102. // For more details, see the memory overcommit documentation
  103. // in vm/overcommit-accounting.
  104. CommitLimit uint64
  105. // The amount of memory presently allocated on the system.
  106. // The committed memory is a sum of all of the memory which
  107. // has been allocated by processes, even if it has not been
  108. // "used" by them as of yet. A process which malloc()'s 1G
  109. // of memory, but only touches 300M of it will show up as
  110. // using 1G. This 1G is memory which has been "committed" to
  111. // by the VM and can be used at any time by the allocating
  112. // application. With strict overcommit enabled on the system
  113. // (mode 2 in 'vm.overcommit_memory'),allocations which would
  114. // exceed the CommitLimit (detailed above) will not be permitted.
  115. // This is useful if one needs to guarantee that processes will
  116. // not fail due to lack of memory once that memory has been
  117. // successfully allocated.
  118. CommittedAS uint64
  119. // total size of vmalloc memory area
  120. VmallocTotal uint64
  121. // amount of vmalloc area which is used
  122. VmallocUsed uint64
  123. // largest contiguous block of vmalloc area which is free
  124. VmallocChunk uint64
  125. HardwareCorrupted uint64
  126. AnonHugePages uint64
  127. ShmemHugePages uint64
  128. ShmemPmdMapped uint64
  129. CmaTotal uint64
  130. CmaFree uint64
  131. HugePagesTotal uint64
  132. HugePagesFree uint64
  133. HugePagesRsvd uint64
  134. HugePagesSurp uint64
  135. Hugepagesize uint64
  136. DirectMap4k uint64
  137. DirectMap2M uint64
  138. DirectMap1G uint64
  139. }
  140. // Meminfo returns an information about current kernel/system memory statistics.
  141. // See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
  142. func (fs FS) Meminfo() (Meminfo, error) {
  143. b, err := util.ReadFileNoStat(fs.proc.Path("meminfo"))
  144. if err != nil {
  145. return Meminfo{}, err
  146. }
  147. m, err := parseMemInfo(bytes.NewReader(b))
  148. if err != nil {
  149. return Meminfo{}, fmt.Errorf("failed to parse meminfo: %v", err)
  150. }
  151. return *m, nil
  152. }
  153. func parseMemInfo(r io.Reader) (*Meminfo, error) {
  154. var m Meminfo
  155. s := bufio.NewScanner(r)
  156. for s.Scan() {
  157. // Each line has at least a name and value; we ignore the unit.
  158. fields := strings.Fields(s.Text())
  159. if len(fields) < 2 {
  160. return nil, fmt.Errorf("malformed meminfo line: %q", s.Text())
  161. }
  162. v, err := strconv.ParseUint(fields[1], 0, 64)
  163. if err != nil {
  164. return nil, err
  165. }
  166. switch fields[0] {
  167. case "MemTotal:":
  168. m.MemTotal = v
  169. case "MemFree:":
  170. m.MemFree = v
  171. case "MemAvailable:":
  172. m.MemAvailable = v
  173. case "Buffers:":
  174. m.Buffers = v
  175. case "Cached:":
  176. m.Cached = v
  177. case "SwapCached:":
  178. m.SwapCached = v
  179. case "Active:":
  180. m.Active = v
  181. case "Inactive:":
  182. m.Inactive = v
  183. case "Active(anon):":
  184. m.ActiveAnon = v
  185. case "Inactive(anon):":
  186. m.InactiveAnon = v
  187. case "Active(file):":
  188. m.ActiveFile = v
  189. case "Inactive(file):":
  190. m.InactiveFile = v
  191. case "Unevictable:":
  192. m.Unevictable = v
  193. case "Mlocked:":
  194. m.Mlocked = v
  195. case "SwapTotal:":
  196. m.SwapTotal = v
  197. case "SwapFree:":
  198. m.SwapFree = v
  199. case "Dirty:":
  200. m.Dirty = v
  201. case "Writeback:":
  202. m.Writeback = v
  203. case "AnonPages:":
  204. m.AnonPages = v
  205. case "Mapped:":
  206. m.Mapped = v
  207. case "Shmem:":
  208. m.Shmem = v
  209. case "Slab:":
  210. m.Slab = v
  211. case "SReclaimable:":
  212. m.SReclaimable = v
  213. case "SUnreclaim:":
  214. m.SUnreclaim = v
  215. case "KernelStack:":
  216. m.KernelStack = v
  217. case "PageTables:":
  218. m.PageTables = v
  219. case "NFS_Unstable:":
  220. m.NFSUnstable = v
  221. case "Bounce:":
  222. m.Bounce = v
  223. case "WritebackTmp:":
  224. m.WritebackTmp = v
  225. case "CommitLimit:":
  226. m.CommitLimit = v
  227. case "Committed_AS:":
  228. m.CommittedAS = v
  229. case "VmallocTotal:":
  230. m.VmallocTotal = v
  231. case "VmallocUsed:":
  232. m.VmallocUsed = v
  233. case "VmallocChunk:":
  234. m.VmallocChunk = v
  235. case "HardwareCorrupted:":
  236. m.HardwareCorrupted = v
  237. case "AnonHugePages:":
  238. m.AnonHugePages = v
  239. case "ShmemHugePages:":
  240. m.ShmemHugePages = v
  241. case "ShmemPmdMapped:":
  242. m.ShmemPmdMapped = v
  243. case "CmaTotal:":
  244. m.CmaTotal = v
  245. case "CmaFree:":
  246. m.CmaFree = v
  247. case "HugePages_Total:":
  248. m.HugePagesTotal = v
  249. case "HugePages_Free:":
  250. m.HugePagesFree = v
  251. case "HugePages_Rsvd:":
  252. m.HugePagesRsvd = v
  253. case "HugePages_Surp:":
  254. m.HugePagesSurp = v
  255. case "Hugepagesize:":
  256. m.Hugepagesize = v
  257. case "DirectMap4k:":
  258. m.DirectMap4k = v
  259. case "DirectMap2M:":
  260. m.DirectMap2M = v
  261. case "DirectMap1G:":
  262. m.DirectMap1G = v
  263. }
  264. }
  265. return &m, nil
  266. }