返回

如何在 Windows 系统中获取线程的内存占用情况?

windows

如何在 Windows 中获取线程的内存使用情况?

问题

在 Windows 环境中,想要获取线程的内存使用情况时,可能会遇到一些困难。常见的错误是使用 GetProcessMemoryInfo 函数,该函数用于获取进程的内存信息,而不是线程的内存信息。而且,未正确使用 GetExitCodeThread 函数来检查线程是否仍在运行。

解决方法

为了准确获取线程的内存使用情况,需要使用 GetThreadMemoryInfo 函数。该函数专门用于获取有关指定线程的内存使用情况的信息。以下代码演示了如何使用 GetThreadMemoryInfo 函数:

#include <windows.h>
#include <psapi.h>

HANDLE threadHandle;
THREAD_MEMORY_COUNTERS tmc;

// 获取线程的内存信息
GetThreadMemoryInfo(threadHandle, &tmc, sizeof(tmc));

// 打印线程的内存使用情况
printf("PageFaultCount: %d\n", tmc.PageFaultCount);
printf("PeakWorkingSetSize: %d\n", tmc.PeakWorkingSetSize);
printf("WorkingSetSize: %d\n", tmc.WorkingSetSize);

此外,为了正确检查线程是否仍在运行,可以在 WaitForSingleObject 函数之后使用 GetExitCodeThread 函数。如果线程仍在运行,则 GetExitCodeThread 函数将返回 STILL_ACTIVE,否则将返回线程的退出代码。

示例代码

将上述解决方法应用到示例代码中,可以获取线程的内存使用情况:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <psapi.h>

struct global_vars {
    clock_t started_at;
    int time_complex;
    double memory_complex;
};

DWORD WINAPI sleeper(LPVOID param) {
    int x[5000];
    for (int i = 0; i < 5000; i++) {
        x[i] = 5000;
    }
    return 0;
}


int main() {
    DWORD thread1id;
    HANDLE thread1 = CreateThread(NULL, 0, sleeper, NULL, 0, &thread1id);

    if (thread1) {
        WaitForSingleObject(thread1, INFINITE);

        int out = 4;
        if (GetExitCodeThread(thread1, &out) == STILL_ACTIVE) {
            printf("TIME OUT!");
            TerminateThread(thread1, -1);
        }

        THREAD_MEMORY_COUNTERS tmc;
        GetThreadMemoryInfo(thread1, &tmc, sizeof(tmc));

        printf("PageFaultCount: %d\n", tmc.PageFaultCount);
        printf("PeakWorkingSetSize: %d\n", tmc.PeakWorkingSetSize);
        printf("WorkingSetSize: %d\n", tmc.WorkingSetSize);
    }

    return 0;
}

通过运行此代码,你将能够准确获取 thread1 的内存使用情况。

常见问题解答

1. 除了 GetThreadMemoryInfo,还有其他方法可以获取线程的内存使用情况吗?

答:GetProcessMemoryInfo 函数也可以用于获取线程的内存使用情况,但它必须与 OpenProcess 函数结合使用以获取线程所属进程的句柄。

2. 如何获取线程的虚拟内存使用情况?

答:使用 VirtualQueryEx 函数,并指定 MEM_COMMITMEM_RESERVE 标记。

3. 如何监控线程的内存使用情况的变化?

答:使用 Performance Monitor 工具,创建一个自定义计数器来监视 Thread Working Set

4. 如何限制线程的内存使用?

答:可以使用 SetThreadQuota 函数来限制线程的虚拟内存使用。

5. 获取线程的内存使用情况有哪些好处?

答:获取线程的内存使用情况可以帮助你诊断内存问题,例如内存泄漏和堆栈溢出。它还可以帮助你优化应用程序的性能和稳定性。