我想编写一个程序,每秒分配一些内存块,然后写出剩余多少内存(我故意不释放任何内存,因为实际用例是模拟内存不足的情况)。这是程序(针对 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,但是从下面的前几行输出中可以看出,可用内存没有显着变化(在 32GB 左右的 RAM 中,可用内存徘徊在 25GB 左右)。我也尝试过较低的数量,10mb 和 100mb,但行为是相同的。
因此,在这个特定的输出中,到第 8 次免费时,我预计已经使用了 8GB 的 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上尝试过类似的事情,但结果是一样的。这也是 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()
请求内存时,操作系统会保留虚拟内存地址 但不会立即分配物理内存页。
只有当程序写入内存时,操作系统才会将这些虚拟地址映射到物理内存页。
这种行为称为延迟分配或过度承诺。操作系统向进程承诺了一些内存,但直到绝对必要时才真正给予它。
如果您想观察可用内存的减少,您需要通过写入分配的内存来强制操作系统提交这些页面:
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;
}