我想编写一个程序,每秒分配一些内存块,然后写出剩余的内存量(我故意不释放任何内存,因为这是模拟内存不足的实际用例).下面是(针对Linux的)程序:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

int main() {
    size_t mbs = 500 * 1000000; // 500mb

    while(true) {
        sleep(1);

        void* tmp = malloc(mbs);

        system("free");
    }
    
    return 0;
}

free的系统调用列出了可用内存,我预计可用内存每秒会减少500MB,但从下面的前几行输出中可以看到,可用内存没有显著变化(在大约32 GB的RAM中,可用内存徘徊在25 GB左右).我也try 了较低的容量,10MB和freeMB,但行为是相同的. 因此,在这个特定的输出中,到第8个空闲时间,我预计已经使用了8 GB的RAM:

user@DESKTOP-DAGF175:/Projects/tmp$ g++ main.cpp
user@DESKTOP-DAGF175:/Projects/tmp$ ./a.out
              total        used        free      shared  buff/cache   available
Mem:       33471660     7338384    25903924       17720      229352    25999544
Swap:       8192000           0     8192000
              total        used        free      shared  buff/cache   available
Mem:       33471660     7330684    25911624       17720      229352    26007244
Swap:       8192000           0     8192000
              total        used        free      shared  buff/cache   available
Mem:       33471660     7327256    25915052       17720      229352    26010672
Swap:       8192000           0     8192000
              total        used        free      shared  buff/cache   available
Mem:       33471660     7325428    25916880       17720      229352    26012500
Swap:       8192000           0     8192000
              total        used        free      shared  buff/cache   available
Mem:       33471660     7325208    25917100       17720      229352    26012720
Swap:       8192000           0     8192000
              total        used        free      shared  buff/cache   available
Mem:       33471660     7321232    25921076       17720      229352    26016696
Swap:       8192000           0     8192000
              total        used        free      shared  buff/cache   available
Mem:       33471660     7321360    25920948       17720      229352    26016568
Swap:       8192000           0     8192000
              total        used        free      shared  buff/cache   available
Mem:       33471660     7318624    25923684       17720      229352    26019304
Swap:       8192000           0     8192000

我也在Windows上try 了类似的东西,但结果是一样的.以下也是Windows代码:

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

int main() {
    size_t mbs = 500 * 1000000; // 500mb

    while(true) {
        Sleep(2);

        void* tmp = malloc(mbs);

        system("systeminfo |find \"Available Physical Memory\"");
    }
    
    return 0;
}

为什么我没有看到消耗的内存有所减少?

推荐答案

您观察到的行为是由现代操作系统处理内存分配的方式造成的.当您使用malloc()请求内存时,操作系统保留虚拟内存地址but doesn't immediately allocate physical memory pages.

只有当程序写入内存时,操作系统才会将这些虚拟地址映射到物理内存页.

这种行为被称为lazy allocationovercommitment.操作系统向进程promise 了一些内存,除非绝对必要,否则不会真正给予它.

如果您想要观察可用内存的减少,则需要通过写入分配的内存来强制操作系统提交这些页面:

const int PAGE_SIZE = 4096; // commonly used page size

int main() {
    size_t mbs = 500 * 1000000; // 500mb

    while(true) {
        sleep(1);

        char* tmp = (char*)malloc(mbs);
        if(tmp == NULL) {
            printf("Allocation failed\n");
            exit(1);
        }

        // Force the OS to commit the memory by writing to it
        for(size_t i = 0; i < mbs; i += PAGE_SIZE) {
            tmp[i] = 0;
        }

        system("free");
    }
    
    return 0;
}

Edit:此外,您还可以使用sysctl接口在Linux中禁用过量使用:

echo 2 > /proc/sys/vm/overcommit_memory 

有效设置:

  • 启发式策略为0(内核将try 估计用户空间分配的空闲内存量)
  • 1表示"总是过量使用"(内核允许所有内存分配,而不管当前的内存分配状态如何)
  • 2表示禁用过量使用

C++相关问答推荐

C如何显示字符串数组中的第一个字母

如何将不同长度的位转换成字节数组?

有没有更简单的方法从用户那里获取数据类型来计算结果

C中的指针增量和减量(*--*++p)

Setenv在c编程中的用法?

如何识别Linux中USB集线器(根)和连接到集线器(根设备)的设备(子设备)?

从uint8_t*转换为char*可接受

防止C++中递归函数使用堆栈内存

致命错误:ASM/rwan ce.h:没有这样的文件或目录.符号链接还不够

指向不同类型的指针是否与公共初始序列规则匹配?

当内存来自Malloc时,将char*转换为另一个指针类型是否违反了严格的别名规则?

如何确保我将使用C标准库函数的函数版本,如&getc";,而不是类似函数的宏版本?

递归打印二维数组(C编程)

C中的char**v*char[]

Malloc和对齐

为什么这个代码的最后一次迭代不能正常工作?

即使客户端不发送数据,也会发生UNIX套接字读取

关于不同C编译器中的__attribute__支持

C 语言中 CORDIC 对数的问题

中位数和众数不正确