memory.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. package cgroup
  2. import (
  3. "path"
  4. )
  5. const maxMemory = 1 << 62
  6. type MemoryStat struct {
  7. RSS uint64
  8. Cache uint64
  9. Limit uint64
  10. }
  11. func (cg *Cgroup) MemoryStat() (*MemoryStat, error) {
  12. if cg.Version == V1 {
  13. return cg.memoryStatV1()
  14. }
  15. return cg.memoryStatV2()
  16. }
  17. func (cg *Cgroup) memoryStatV1() (*MemoryStat, error) {
  18. vars, err := readVariablesFromFile(path.Join(cgRoot, "memory", cg.subsystems["memory"], "memory.stat"))
  19. if err != nil {
  20. return nil, err
  21. }
  22. limit, err := readUintFromFile(path.Join(cgRoot, "memory", cg.subsystems["memory"], "memory.limit_in_bytes"))
  23. if err != nil {
  24. return nil, err
  25. }
  26. if limit > maxMemory {
  27. limit = 0
  28. }
  29. // Note from https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt:
  30. // Only anonymous and swap cache memory is listed as part of 'rss' stat.
  31. // This should not be confused with the true 'resident set size' or the
  32. // amount of physical memory used by the cgroup.
  33. // 'rss + mapped_file" will give you resident set size of cgroup.
  34. // (Note: file and shmem may be shared among other cgroups. In that case,
  35. // mapped_file is accounted only when the memory cgroup is owner of page
  36. // cache.)
  37. return &MemoryStat{
  38. RSS: vars["rss"] + vars["mapped_file"],
  39. Cache: vars["cache"],
  40. Limit: limit,
  41. }, nil
  42. }
  43. func (cg *Cgroup) memoryStatV2() (*MemoryStat, error) {
  44. vars, err := readVariablesFromFile(path.Join(cgRoot, cg.subsystems[""], "memory.stat"))
  45. if err != nil {
  46. return nil, err
  47. }
  48. limit, _ := readUintFromFile(path.Join(cgRoot, cg.subsystems[""], "memory.max"))
  49. return &MemoryStat{
  50. RSS: vars["anon"] + vars["file_mapped"],
  51. Cache: vars["file"],
  52. Limit: limit,
  53. }, nil
  54. }