From 195b01ddc73ce98d57089ffcd333baaa897dc0cb Mon Sep 17 00:00:00 2001 From: Daniel Widdis Date: Wed, 23 Feb 2022 12:32:05 -0600 Subject: [PATCH 1/2] Use system-level values for Windows virtual memory Submitting this as a draft PR as I believe it will address #2074. I do not have either a C or Python development environment to test these changes, so they are provided in the hopes someone else can test and confirm they fix the issue. There's probably some room to simplify the code with temporary variables to reduce redundancy. For background, I have implemented precisely this logic in my own (Java-based) project [here](https://github.com/oshi/oshi/blob/3bb9eafbe2062edad4108b7b12501b1f9be27361/oshi-core/src/main/java/oshi/hardware/platform/windows/WindowsVirtualMemory.java#L110-L118) and [here](https://github.com/oshi/oshi/blob/3bb9eafbe2062edad4108b7b12501b1f9be27361/oshi-core/src/main/java/oshi/hardware/platform/windows/WindowsGlobalMemory.java#L253-L263) following a detailed investigation in https://github.com/oshi/oshi/issues/1182 Signed-off-by: Daniel Widdis --- psutil/_psutil_windows.c | 25 ++++++++++++++----------- psutil/_pswindows.py | 5 ++--- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/psutil/_psutil_windows.c b/psutil/_psutil_windows.c index 83da3a26c..97e2d130e 100644 --- a/psutil/_psutil_windows.c +++ b/psutil/_psutil_windows.c @@ -610,20 +610,23 @@ psutil_proc_memory_uss(PyObject *self, PyObject *args) { */ static PyObject * psutil_virtual_mem(PyObject *self, PyObject *args) { - MEMORYSTATUSEX memInfo; - memInfo.dwLength = sizeof(MEMORYSTATUSEX); - - if (! GlobalMemoryStatusEx(&memInfo)) { + unsigned long long totalPhys, availPhys, totalSys, availSys, pageSize; + PERFORMANCE_INFORMATION perfInfo; + if (! GetPerformanceInfo(&perfInfo, sizeof(PERFORMANCE_INFORMATION))) { PyErr_SetFromWindowsErr(0); return NULL; } - return Py_BuildValue("(LLLLLL)", - memInfo.ullTotalPhys, // total - memInfo.ullAvailPhys, // avail - memInfo.ullTotalPageFile, // total page file - memInfo.ullAvailPageFile, // avail page file - memInfo.ullTotalVirtual, // total virtual - memInfo.ullAvailVirtual); // avail virtual + // values are size_t, widen to long long + pageSize = perfInfo.PageSize; + totalPhys = perfInfo.PhysicalTotal * pageSize; + availPhys = perfInfo.PhysicalAvailable * pageSize; + totalSys = perfInfo.CommitLimit * pageSize; + availSys = totalSys - perfInfo.CommitTotal * pageSize; + return Py_BuildValue("(LLLL)", + totalPhys, + availPhys, + totalSys, + availSys); } diff --git a/psutil/_pswindows.py b/psutil/_pswindows.py index 7d882b774..352e1b856 100644 --- a/psutil/_pswindows.py +++ b/psutil/_pswindows.py @@ -229,7 +229,7 @@ def getpagesize(): def virtual_memory(): """System virtual memory as a namedtuple.""" mem = cext.virtual_mem() - totphys, availphys, totpagef, availpagef, totvirt, freevirt = mem + totphys, availphys, totsys, availsys = mem # total = totphys avail = availphys @@ -248,8 +248,7 @@ def swap_memory(): total_system = mem[2] free_system = mem[3] - # Despite the name PageFile refers to total system memory here - # thus physical memory values need to be subtracted to get swap values + # physical memory values need to be substracted to get swap values total = total_system - total_phys free = min(total, free_system - free_phys) used = total - free From 066c4c1e498dfb8aeb1ad864dd83524a1f8f1840 Mon Sep 17 00:00:00 2001 From: Daniel Widdis Date: Thu, 20 Oct 2022 16:07:17 -0700 Subject: [PATCH 2/2] Formatting, credits, change log Signed-off-by: Daniel Widdis --- CREDITS | 4 ++++ HISTORY.rst | 10 ++++++++++ psutil/_psutil_windows.c | 14 ++++++++------ psutil/_pswindows.py | 3 ++- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/CREDITS b/CREDITS index 6f1b6e5b8..29298ca3e 100644 --- a/CREDITS +++ b/CREDITS @@ -801,3 +801,7 @@ I: 2135 N: Daniel Li I: 2150 + +N: Daniel Widdis +W: https://github.com/dbwiddis +I: 2077 diff --git a/HISTORY.rst b/HISTORY.rst index e98339901..f0d0905d4 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,5 +1,15 @@ *Bug tracker at https://github.com/giampaolo/psutil/issues* +5.9.4 (IN DEVELOPMENT) +====================== + +XXXX-XX-XX + +**Bug fixes** + +- 2077_, [Windows]: Use system-level values for `virtual_memory()`. (patch by + Daniel Widdis) + 5.9.3 ===== diff --git a/psutil/_psutil_windows.c b/psutil/_psutil_windows.c index 97e2d130e..6e51c449d 100644 --- a/psutil/_psutil_windows.c +++ b/psutil/_psutil_windows.c @@ -612,21 +612,23 @@ static PyObject * psutil_virtual_mem(PyObject *self, PyObject *args) { unsigned long long totalPhys, availPhys, totalSys, availSys, pageSize; PERFORMANCE_INFORMATION perfInfo; + if (! GetPerformanceInfo(&perfInfo, sizeof(PERFORMANCE_INFORMATION))) { PyErr_SetFromWindowsErr(0); return NULL; } - // values are size_t, widen to long long + // values are size_t, widen (if needed) to long long pageSize = perfInfo.PageSize; totalPhys = perfInfo.PhysicalTotal * pageSize; availPhys = perfInfo.PhysicalAvailable * pageSize; totalSys = perfInfo.CommitLimit * pageSize; availSys = totalSys - perfInfo.CommitTotal * pageSize; - return Py_BuildValue("(LLLL)", - totalPhys, - availPhys, - totalSys, - availSys); + return Py_BuildValue( + "(LLLL)", + totalPhys, + availPhys, + totalSys, + availSys); } diff --git a/psutil/_pswindows.py b/psutil/_pswindows.py index 352e1b856..b546f15d8 100644 --- a/psutil/_pswindows.py +++ b/psutil/_pswindows.py @@ -248,7 +248,8 @@ def swap_memory(): total_system = mem[2] free_system = mem[3] - # physical memory values need to be substracted to get swap values + # system memory (commit total/limit) is the sum of physical and swap + # thus physical memory values need to be substracted to get swap values total = total_system - total_phys free = min(total, free_system - free_phys) used = total - free