-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use system-level values for Windows virtual memory #2077
Conversation
Looking back at this, it seems Appveyor signals a problem: https://ci.appveyor.com/project/giampaolo/psutil/builds/42685706/job/pmmgoyuraqv158ca
|
Which is why it's in draft. :) Looks like possible overflow, I'll look into it. |
OK, I've checked and double checked and triple checked the values and they should be correct. I'm wondering if there's something different about accessing the values in a structure. The -877076026483515392L value is probably not overflow; the value is way too large to even make sense. Looking at the binary of that is suspicious. Here it is split into 4 16-bit segments.
It seems odd that the second set of 16 bits are all 0's, and it makes me wonder if there's an alignment or endianness issue. Digging around I see a calculation in Hadoop similar to what I did: PERFORMANCE_INFORMATION memInfo;
// ... next 2 lines might be needed?
ZeroMemory(&memInfo, sizeof(PERFORMANCE_INFORMATION));
memInfo.cb = sizeof(PERFORMANCE_INFORMATION);
if(!GetPerformanceInfo(&memInfo, sizeof(PERFORMANCE_INFORMATION)))
{
ReportErrorCode(L"GetPerformanceInfo", GetLastError());
return EXIT_FAILURE;
}
vmemSize = memInfo.CommitLimit*memInfo.PageSize;
vmemFree = vmemSize - memInfo.CommitTotal*memInfo.PageSize;
memSize = memInfo.PhysicalTotal*memInfo.PageSize;
memFree = memInfo.PhysicalAvailable*memInfo.PageSize; which aligns with my change (some lines omitted and re-ordered to match, but no math changed): PERFORMANCE_INFORMATION perfInfo;
if (! GetPerformanceInfo(&perfInfo, sizeof(PERFORMANCE_INFORMATION))) {
PyErr_SetFromWindowsErr(0);
return NULL;
}
return Py_BuildValue("(LLLLLL)",
perfInfo.CommitLimit * perfInfo.PageSize, // total virtual
(perfInfo.CommitLimit - perfInfo.CommitTotal) * perfInfo.PageSize); // avail virtual
perfInfo.PhysicalTotal * perfInfo.PageSize, // total
perfInfo.PhysicalAvailable * perfInfo.PageSize, // avail The only difference seems to be that the Hadoop code zeros the memory prior to the call and then sets the I don't have a windows machine to do much debugging here, but if it's possible for anyone to compare the two sets of numbers, the following values should be equal: perfinfo.CommitLimit = memInfo.ullTotalPageFile / perfinfo.PageSize;
perfinfo.PhysicalTotal = memInfo.ullTotalPhys / perfinfo.PageSize;
perfinfo.PhysicalAvailable = memInfo.ullAvailPhys / perfinfo.PageSize; I'm going to update the PR to include the setting of |
Now the magic failure number is -927284125454278656L. Some parts of the binary representation match (the lowest 32 bits), others don't:
|
One thought: the values in |
You're making me learn C and/or Python. This is not fair. :) On the bright side, I see handling of |
8748396
to
326496b
Compare
Good news is I figured out the appropriate syntax to get the values. Bad news is that the meaning assigned to those values differs here and at my own project, so tests are currently failing. I'll do some experimenting over the next week to line up the numbers to report the same thing, and flip this into ready for review when I think I've solved it. |
Thank you Daniel. |
f2b7e19
to
1fd5950
Compare
OK, that was painfully long for a very simple fix. The root cause was in fact overflow (multiplying two 32-bit size_t values and getting a 33-bit result) and I was overcomplicating how to handle it. Should be good to go now! |
Oh, forgot to add, only the first 4 values of the MEMORYSTATUSEX struct had corresponding values in PERFORMANCE_INFORMATION, but the last two values are calling-process based and are never used, so I just removed them. |
Submitting this as a draft PR as I believe it will address giampaolo#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 oshi/oshi#1182 Signed-off-by: Daniel Widdis <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a couple of minor notes but overall looks good and appveyor tests are not complaining.
Also, can you please update HISTORY and CREDITS files? |
Signed-off-by: Daniel Widdis <[email protected]>
Merged. Thanks Daniel. |
Daniel, since this didn't fix the problem I think it's safer to revert this PR. The main reason is because this same C function is used also for Do you agree on reverting this? |
I'm a little late on seeing this, but for completeness I'll say "no". My reasoning:
|
* 'master' of https://github.com/giampaolo/psutil: add windows test for free physical mem giampaolo#2074 fix OSX tests broken by accident update HISTORY + give CREDITS for @arossert, @smoofra, @mayeut for giampaolo#2102, giampaolo#2156, giampaolo#2010 build fix for Mac OS, Apple Silicon (giampaolo#2010) Linux: fix missing SPEED_UNKNOWN definition (giampaolo#2156) Use system-level values for Windows virtual memory (giampaolo#2077) feature: use ABI3 for cp36+ (giampaolo#2102) fix py2 compatibility improve API speed benchmark script giampaolo#2102 fix: linter issues from giampaolo#2146 (giampaolo#2155) chore: skip test_cpu_freq on macOS arm64 (giampaolo#2146) pre-release + give CREDITS to @mayeut (PR giampaolo#2040) and @eallrich (new supporter) Fix a typo (giampaolo#2047) move isort and coverage config into pyproject.toml fix giampaolo#2021, fix giampaolo#1954, provide OSX arm64 bins + add pyproject.toml (giampaolo#2040) refactor git_log.py
Summary
Description
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 and here following a detailed investigation in oshi/oshi#1182