You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows10下C++程序如何限制自身物理内存占用?

在Windows 10下用C++限制进程内存的正确方法

你的问题出在没有启用Job Object的内存限制标志——Windows只会在你明确告诉它要启用某个限制时,才会生效对应的参数。你的代码里只设置了MaximumWorkingSetSize,但没在LimitFlags里标记要启用这个限制,所以系统直接忽略了这个值。

我来给你修正代码,并解释关键要点:

关键问题分析

  1. 未设置LimitFlags:JOBOBJECT_EXTENDED_LIMIT_INFORMATION中的BasicLimitInformation.LimitFlags必须包含对应的限制标志(比如JOB_OBJECT_LIMIT_WORKINGSET),否则系统不会应用你设置的MaximumWorkingSetSize。
  2. WorkingSetSize的单位是页面:每个页面默认是4KB,所以你设置的1其实是4KB,但建议设置合理的测试值(比如1MB=256个页面),避免进程直接崩溃。
  3. 进程归属检查:确保当前进程没有被其他Job对象包含,否则AssignProcessToJobObject会失败。

修正后的代码示例

#include <windows.h>
#include <stdexcept>
#include <iostream>

void LimitProcessMemory() {
    // 创建Job对象
    HANDLE hJob = CreateJobObject(nullptr, L"MyMemoryLimitJob");
    if (hJob == nullptr) {
        throw std::runtime_error("Failed to create job object: " + std::to_string(GetLastError()));
    }

    // 检查当前进程是否已经在某个Job中
    BOOL isInJob = FALSE;
    if (!IsProcessInJob(GetCurrentProcess(), nullptr, &isInJob)) {
        CloseHandle(hJob);
        throw std::runtime_error("Failed to check process job membership: " + std::to_string(GetLastError()));
    }
    if (isInJob) {
        CloseHandle(hJob);
        throw std::runtime_error("Process is already in a job, cannot assign to new job");
    }

    // 将当前进程分配到Job中
    if (!AssignProcessToJobObject(hJob, GetCurrentProcess())) {
        CloseHandle(hJob);
        throw std::runtime_error("Failed to assign process to job: " + std::to_string(GetLastError()));
    }

    // 配置内存限制
    JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobLimits = {0};
    // 启用工作集(物理内存)限制
    jobLimits.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_WORKINGSET;
    // 设置最小/最大工作集大小(单位:页面,1页面=4KB)
    // 这里设置最大为1MB(256*4KB),最小为64KB(16*4KB)
    jobLimits.BasicLimitInformation.MinimumWorkingSetSize = 16;
    jobLimits.BasicLimitInformation.MaximumWorkingSetSize = 256;

    // 可选:如果要限制虚拟内存总量(更严格的内存限制)
    // jobLimits.BasicLimitInformation.LimitFlags |= JOB_OBJECT_LIMIT_VM_SIZE;
    // jobLimits.VirtualMemoryLimit = 1024 * 1024 * 1024; // 1GB虚拟内存限制

    // 应用限制
    if (!SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, &jobLimits, sizeof(jobLimits))) {
        CloseHandle(hJob);
        throw std::runtime_error("Failed to set job limits: " + std::to_string(GetLastError()));
    }

    std::cout << "Memory limit applied successfully" << std::endl;
}

int main() {
    try {
        LimitProcessMemory();
        // 这里写你的业务代码,测试内存占用
        // 比如尝试分配大量内存,会触发系统限制
        char* bigBuffer = new char[2 * 1024 * 1024]; // 尝试分配2MB,超过1MB工作集限制
        delete[] bigBuffer;
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return 1;
    }
    return 0;
}

额外说明

  • 工作集限制 vs 虚拟内存限制:
    • JOB_OBJECT_LIMIT_WORKINGSET限制的是进程能使用的物理内存大小,系统会主动将超出部分的内存页交换到磁盘。
    • JOB_OBJECT_LIMIT_VM_SIZE限制的是进程能分配的虚拟内存总量,一旦超过,内存分配操作(new/malloc)会失败(返回NULL或抛出std::bad_alloc),这种限制更严格。
  • 权限问题:确保程序以足够的权限运行(普通用户权限通常足够,但如果进程是受保护的进程可能会失败)。
  • Job对象的生命周期:Job对象会在所有关联进程退出后自动关闭,也可以手动调用CloseHandle关闭。

内容的提问来源于stack exchange,提问作者Dominique

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:35:30