I'm trying to get the sizes of the shareable and shared working sets of a process.
This is the code that I use:
internal static unsafe WorkingSetInfo? GetWorkingSetInfo(SafeProcessHandle processHandle)
{
Settings.Log.Info("Called method: GetWorkingSetInfo");
uint size = 16;
void* pointer = Alloc(size);
int error;
Settings.Log.Debug("Retrieving info on working set...");
bool result = QueryWorkingSet(processHandle, pointer, size);
while (!result)
{
error = GetLastPInvokeError();
if (error is ERROR_BAD_LENGTH)
{
size *= 2;
pointer = Realloc(pointer, size);
result = QueryWorkingSet(processHandle, pointer, size);
}
else
{
Settings.Log.DebugFormat("Failed to retrieve info on working set: {0} ({1})", GetLastPInvokeErrorMessage(), error);
Free(pointer);
return null;
}
}
PSAPI_WORKING_SET_INFORMATION info = new();
ulong* dataPointer = (ulong*)pointer;
info.NumberOfEntries = new(*dataPointer);
dataPointer += 1;
info.WorkingSetInfo = new nuint[info.NumberOfEntries];
for (var i = 0; i < info.NumberOfEntries.ToUInt32(); i++)
{
info.WorkingSetInfo[i] = new(*dataPointer);
dataPointer += 1;
}
Free(pointer);
uint pageSize = GetMemoryPageSize();
return new(info, pageSize);
}
This code works correctly, but it is also inefficient. Whenever it runs, the CPU usage of my process rises to around 30% (the average is 10% when it does not run).
Is there a way to optimize it, or an alternate way to get the data (I use the QueryWorkingSet function)?
I can use the Native API if there is no alternative.