windows 为什么挂起的程序会增加其内存使用

vhmi4jdf  于 2023-01-06  发布在  Windows
关注(0)|答案(1)|浏览(122)

在Visual Studio中开发的一个名为monitor的C++后台程序监视另一个名为target的程序,并在每次退出时重新启动该程序。下面显示了该程序的简化版本。

#include <windows.h>
#include <tlhelp32.h>
#include <Process.h>

void BindToProcess();

const WCHAR PATH[] = L"C:\\Windows\\System32\\notepad.exe";
const WCHAR EXE[] = L"notepad.exe";

int CALLBACK WinMain(
    _In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPSTR lpCmdLine,
    _In_ int nShowCmd)
{
    do
    {
        BindToProcess();
        _wspawnl(_P_WAIT, PATH, PATH, NULL);
    } while (TRUE);
    return 0;
}

void BindToProcess()
{
    HANDLE hProcessSnap;
    PROCESSENTRY32 pe32;

    // Take a snapshot of all processes in the system.
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE) return;

    // Set the size of the structure before using it.
    pe32.dwSize = sizeof(PROCESSENTRY32);

    // Retrieve information about the first process,
    if (!Process32First(hProcessSnap, &pe32))
    {
        CloseHandle(hProcessSnap);
        return;
    }

    // Now walk the snapshot of processes, and search for target
    do
    {
        const int len = (int) wcsnlen_s(EXE, 10);
        if (CompareStringW(0, 0, pe32.szExeFile, len, EXE, len) == CSTR_EQUAL)
        {
            HANDLE handle[1];
            handle[0] = OpenProcess(SYNCHRONIZE, FALSE, pe32.th32ProcessID);
            WaitForMultipleObjects(1, handle, TRUE, INFINITE);
            CloseHandle(handle[0]);
            CloseHandle(hProcessSnap);
            return;
        }
    } while (Process32Next(hProcessSnap, &pe32));
    CloseHandle(hProcessSnap);
    return;
}

Monitor首先检查target是否正在运行,如果正在运行,则将其自身绑定到target。它将保持不活动状态,直到target存在。然后,它将重新启动target,并再次保持不活动状态,直到target存在,以便再次重新启动它。
在mockup程序中,我使用notepad.exe作为目标,在真实的系统中,它是一个搜索互联网并将结果显示在图形用户界面中的应用程序,在实践中,target除非被故意杀死,否则永远不会退出,因此monitor不会循环;它仍然悬着。然而,我观察到它的记忆力在增长。
Monitor从不使用new()malloc()来分配内存。只有在调用CreateToolhelp32Snapshot()OpenProcess()时才会分配内存,但相应的内存是通过调用CloseHandle()释放的。因此,即使程序在循环,也不会发生内存泄漏,但如果程序没有循环,就会挂起。
为什么挂起的程序内存会增长?我观察到内存增加和内存减少,但从长远来看,内存会增长。

f0ofjuux

f0ofjuux1#

这是因为程序访问的信息是可变的。
CreateToolhelp32Snapshot()并不总是具有相同的内存使用量,因为它是进程在任何给定时间的快照。进程变化很大,一些可以关闭,另一些可以启动。
快照的进程信息也会变化,例如,您正在检查szExeFile,它没有固定大小。
另外,内存分配有时是以块为单位的,所以一次运行可以保留一个更大或更小的块,这取决于可用的块。
只要内存不无限增长,这种行为就是正常的。

相关问题