|
发表于 2019-9-11 15:16:16
|
显示全部楼层
浙江省杭州市
Private WS,专用工作集,即任务管理器默认显示的[内存大小][6],微软并没有给出API来获取这个值
数据类型
typedef struct _MEMORY_WORKING_SET_BLOCK
{
ULONG_PTR Protection : 5;
ULONG_PTR ShareCount : 3;
ULONG_PTR Shared : 1;
ULONG_PTR Node : 3;
#ifdef _WIN64
ULONG_PTR VirtualPage : 52;
#else
ULONG VirtualPage : 20;
#endif
} MEMORY_WORKING_SET_BLOCK, *PMEMORY_WORKING_SET_BLOCK;
typedef struct _MEMORY_WORKING_SET_INFORMATION
{
ULONG_PTR NumberOfEntries;
MEMORY_WORKING_SET_BLOCK WorkingSetInfo[1];
} MEMORY_WORKING_SET_INFORMATION, *PMEMORY_WORKING_SET_INFORMATION;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
MEMORY_INFORMATION_CLASS
typedef enum _MEMORY_INFORMATION_CLASS
{
MemoryBasicInformation, // MEMORY_BASIC_INFORMATION
MemoryWorkingSetInformation, // MEMORY_WORKING_SET_INFORMATION
MemoryMappedFilenameInformation, // UNICODE_STRING
MemoryRegionInformation, // MEMORY_REGION_INFORMATION
MemoryWorkingSetExInformation, // MEMORY_WORKING_SET_EX_INFORMATION
MemorySharedCommitInformation, // MEMORY_SHARED_COMMIT_INFORMATION
MemoryImageInformation // MEMORY_IMAGE_INFORMATION
} MEMORY_INFORMATION_CLASS;
1
2
3
4
5
6
7
8
9
10
实现代码
NTSTATUS GetProcessWorkingSetInformation(
_In_ HANDLE ProcessHandle,
_Out_ PMEMORY_WORKING_SET_INFORMATION *WorkingSetInformation
)
{
NTSTATUS status = STATUS_SUCCESS;
PVOID buffer = NULL;
SIZE_T bufferSize = 0;
bufferSize = 0x800;
buffer = malloc(bufferSize);
while ((status = NtQueryVirtualMemory(
ProcessHandle,
NULL,
MemoryWorkingSetInformation,
buffer,
bufferSize,
NULL
)) == STATUS_INFO_LENGTH_MISMATCH)
{
free(buffer);
bufferSize *= 2;
// Fail if we're resizing the buffer to something very large.
if (bufferSize > PH_LARGE_BUFFER_SIZE)
return STATUS_INSUFFICIENT_RESOURCES;
buffer = malloc(bufferSize);
}
if (!NT_SUCCESS(status))
{
free(buffer);
return status;
}
*WorkingSetInformation = (PMEMORY_WORKING_SET_INFORMATION)buffer;
return status;
}
NTSTATUS GetProcessWsCounters(
_In_ HANDLE ProcessHandle,
_Out_ PPROCESS_WS_COUNTERS WsCounters
)
{
NTSTATUS status = STATUS_SUCCESS;
PMEMORY_WORKING_SET_INFORMATION wsInfo = NULL;
PROCESS_WS_COUNTERS wsCounters = {0};
ULONG i = 0;
if (!NT_SUCCESS(status = GetProcessWorkingSetInformation(
ProcessHandle,
&wsInfo
)))
return status;
memset(&wsCounters, 0, sizeof(PROCESS_WS_COUNTERS));
for (i = 0; i < wsInfo->NumberOfEntries; i++)
{
wsCounters.NumberOfPages++;
if (wsInfo->WorkingSetInfo[i].ShareCount > 1)
wsCounters.NumberOfSharedPages++;
if (wsInfo->WorkingSetInfo[i].ShareCount == 0)
wsCounters.NumberOfPrivatePages++;
if (wsInfo->WorkingSetInfo[i].Shared)
wsCounters.NumberOfShareablePages++;
}
free(wsInfo);
*WsCounters = wsCounters;
return status;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
调用
PROCESS_WS_COUNTERS wsCounters = { 0 };
SIZE_T PrivateWS = 0;
//// Try to open a process handle with PROCESS_QUERY_INFORMATION access for
// WS information.
GetProcessWsCounters(hProcess, &wsCounters);
PrivateWS = wsCounters.NumberOfPrivatePages * PAGE_SIZE;
1
2
3
4
5
6
How to get page size
SYSTEM_INFO SysInfo = { 0 };
DWORD dwPageSize = 0;
GetSystemInfo( &SysInfo );
dwPageSize = SysInfo.dwPageSize; |
|