summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2016-09-18 16:04:51 +0200
committerGiampaolo Rodola <g.rodola@gmail.com>2016-09-18 16:04:51 +0200
commite67cf876f4e987d7f3ceebe3bd6caecf20086fa3 (patch)
tree4f6a87d7110d974412e742c0883b94dbab5988fe
parent4ef75441af929750309fecbe6a0e49a2a6f03b05 (diff)
downloadpsutil-e67cf876f4e987d7f3ceebe3bd6caecf20086fa3.tar.gz
#887: match 'available' column of 'free'; also calculate 'cached' mem the same way free does (includes reclaimable mem)
-rw-r--r--psutil/__init__.py2
-rw-r--r--psutil/_pslinux.py70
2 files changed, 32 insertions, 40 deletions
diff --git a/psutil/__init__.py b/psutil/__init__.py
index 0a6f3ec6..020a0bdd 100644
--- a/psutil/__init__.py
+++ b/psutil/__init__.py
@@ -187,7 +187,7 @@ __all__ = [
]
__all__.extend(_psplatform.__extra__all__)
__author__ = "Giampaolo Rodola'"
-__version__ = "4.3.2"
+__version__ = "4.4.0"
version_info = tuple([int(num) for num in __version__.split('.')])
AF_LINK = _psplatform.AF_LINK
_TOTAL_PHYMEM = None
diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py
index 7f6e0405..82f79074 100644
--- a/psutil/_pslinux.py
+++ b/psutil/_pslinux.py
@@ -299,47 +299,39 @@ def virtual_memory():
if shared == 0:
shared = None
- cached = active = inactive = None
+ mems = {}
with open_binary('%s/meminfo' % get_procfs_path()) as f:
for line in f:
- if cached is None and line.startswith(b"Cached:"):
- cached = int(line.split()[1]) * 1024
- elif active is None and line.startswith(b"Active:"):
- active = int(line.split()[1]) * 1024
- elif inactive is None and line.startswith(b"Inactive:"):
- inactive = int(line.split()[1]) * 1024
- # From "man free":
- # The shared memory column represents either the MemShared
- # value (2.4 kernels) or the Shmem value (2.6+ kernels) taken
- # from the /proc/meminfo file. The value is zero if none of
- # the entries is exported by the kernel.
- elif shared is None and \
- line.startswith(b"MemShared:") or \
- line.startswith(b"Shmem:"):
- shared = int(line.split()[1]) * 1024
-
- missing = []
- if cached is None:
- missing.append('cached')
- cached = 0
- if active is None:
- missing.append('active')
- active = 0
- if inactive is None:
- missing.append('inactive')
- inactive = 0
- if shared is None:
- missing.append('shared')
- shared = 0
- if missing:
- msg = "%s memory stats couldn't be determined and %s set to 0" % (
- ", ".join(missing),
- "was" if len(missing) == 1 else "were")
- warnings.warn(msg, RuntimeWarning)
-
- # Note: this value matches "htop" perfectly.
- avail = free + buffers + cached
- # Note: this value matches "free", but not all the time, see:
+ fields = line.split()
+ mems[fields[0]] = int(fields[1]) * 1024
+
+ # Match "free" cmdline utility:
+ # https://gitlab.com/procps-ng/procps/
+ # blob/195565746136d09333ded280cf3ba93853e855b8/proc/sysinfo.c#L761
+ cached = mems.get(b"Cached:", 0) + mems.get(b"SReclaimable:", 0)
+
+ active = mems.get(b"Active:", 0)
+
+ # Match "free" cmdline utility in case "Inactive:" is not there:
+ # https://gitlab.com/procps-ng/procps/
+ # blob/195565746136d09333ded280cf3ba93853e855b8/proc/sysinfo.c#L758
+ inactive = mems.get(b"Inactive:", 0)
+ if inactive == 0:
+ inactive = \
+ mems.get(b"Inact_dirty:", 0) + \
+ mems.get(b"Inact_clean:", 0) + \
+ mems.get(b"Inact_laundry:", 0)
+
+ # Note: starting from 4.4.0 we match "free" "available" column.
+ # Before 4.4.0 we calculated it as:
+ # >>> avail = free + buffers + cached
+ # ...which matched htop.
+ # free and htop available memory differs as per:
+ # http://askubuntu.com/a/369589
+ # http://unix.stackexchange.com/a/65852/168884
+ avail = mems['MemAvailable:']
+
+ # XXX: this value matches "free", but not all the time, see:
# https://github.com/giampaolo/psutil/issues/685#issuecomment-202914057
used = total - free
# Note: this value matches "htop" perfectly.