Created
May 27, 2019 19:49
-
-
Save AndreyBazhan/1b984fac80e79bb17c03d4a8fc981384 to your computer and use it in GitHub Desktop.
Process Explorer: Process Properties->Performance tab performance issue
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Windows.h> | |
#include <psapi.h> | |
int main() | |
{ | |
HANDLE ProcessHandle; | |
ULONG Processes[4096]; | |
ULONG DataSize; | |
ULONG NumberOfProcesses; | |
ULONG i; | |
for ( ; ; ) { | |
if (!EnumProcesses(Processes, sizeof(Processes), &DataSize)) { | |
return 1; | |
} | |
NumberOfProcesses = DataSize / sizeof(ULONG); | |
for (i = 0; i < NumberOfProcesses; i++) { | |
ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, | |
FALSE, | |
Processes[i]); | |
if (ProcessHandle) { | |
PSAPI_WORKING_SET_INFORMATION WorkingSetInformation; | |
PPSAPI_WORKING_SET_INFORMATION Buffer = NULL; | |
ULONG BufferSize = 0; | |
ULONG LastError; | |
BOOL IsOk; | |
#if 1 | |
// | |
// This is the current approach to get working set information in Process Explorer v16.22 in Process Properties dialog. | |
// For a process with working set 10 GB it takes 1281 ((((10 * 1024 * 1024 * 1024) / 4096) * 8 + 8) / 16384 + 1) loops to get working set information. | |
// Note that in main window it uses allocated buffer from the first process query and if the process's working set were increased it will add 0x4000 | |
// to the current buffer size, so the issue is slightly mitigated. | |
// | |
for ( ; ; ) { | |
IsOk = QueryWorkingSet(ProcessHandle, Buffer, BufferSize); | |
if (IsOk && Buffer && ((((ULONG)Buffer->NumberOfEntries * RTL_FIELD_SIZE(PSAPI_WORKING_SET_INFORMATION, NumberOfEntries)) + FIELD_OFFSET(PSAPI_WORKING_SET_INFORMATION, WorkingSetInfo)) <= BufferSize)) { | |
break; | |
} | |
if (Buffer) { | |
HeapFree(GetProcessHeap(), 0, Buffer); | |
Buffer = NULL; | |
} | |
LastError = GetLastError(); | |
if (LastError != ERROR_BAD_LENGTH) { | |
break; | |
} | |
BufferSize += 0x4000; | |
Buffer = (PPSAPI_WORKING_SET_INFORMATION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, BufferSize); | |
} | |
#else | |
// | |
// This is the approach with one loop. | |
// | |
for ( ; ; ) { | |
Buffer = &WorkingSetInformation; | |
BufferSize = sizeof(WorkingSetInformation); | |
IsOk = QueryWorkingSet(ProcessHandle, Buffer, BufferSize); | |
if (IsOk) { | |
break; | |
} | |
LastError = GetLastError(); | |
if (LastError != ERROR_BAD_LENGTH) { | |
break; | |
} | |
if (!Buffer->NumberOfEntries) { | |
break; | |
} | |
BufferSize = ((ULONG)Buffer->NumberOfEntries * RTL_FIELD_SIZE(PSAPI_WORKING_SET_INFORMATION, NumberOfEntries)) + FIELD_OFFSET(PSAPI_WORKING_SET_INFORMATION, WorkingSetInfo); | |
Buffer = (PPSAPI_WORKING_SET_INFORMATION)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, BufferSize); | |
if (Buffer) { | |
IsOk = QueryWorkingSet(ProcessHandle, Buffer, BufferSize); | |
if (IsOk) { | |
break; | |
} | |
else { | |
HeapFree(GetProcessHeap(), 0, Buffer); | |
Buffer = NULL; | |
} | |
} | |
} | |
#endif | |
if (Buffer && (Buffer != &WorkingSetInformation)) { | |
HeapFree(GetProcessHeap(), 0, Buffer); | |
Buffer = NULL; | |
} | |
CloseHandle(ProcessHandle); | |
} | |
} | |
Sleep(1000); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment