cHa*_*Ham 8 c linux memory malloc mmap
我知道这可能是一个愚蠢的问题,但我一直在寻找一段时间,但无法找到明确的答案.如果我使用mmap
或malloc
(在C中,在Linux机器上)任何一个在RAM中分配空间?例如,如果我有2GB的RAM并且想要使用所有可用的RAM,我可以使用malloc/memset
组合mmap
,或者是否有另一种我不知道的选项?
我想编写一系列可以同时运行的简单程序,并保持进程中使用的所有RAM强制使用交换,并且频繁地交换页面.我已经尝试过以下程序,但这并不是我想要的.它确实分配内存(RAM?),并强制使用交换(如果有足够的实例正在运行),但是当我调用时sleep
不会只是锁定内存被使用(因此实际上没有任何内容与其他内容进行交换)过程?),或者我误解了什么.
例如,如果我运行了3次,那么我将使用前两个实例中的2GB(全部)RAM,然后第三个实例会将前两个实例中的一个(RAM)和当前实例交换到RAM中吗?或者实例#3是否只使用磁盘或虚拟内存运行?
这提出了另一点,我是否需要分配足够的内存来使用所有可用的虚拟内存以及要使用的交换分区?
最后,将mmap
(或任何其他C函数.地狱,甚至是另一种语言,如果适用)更好地做到这一点?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MB(size) ( (size) * 1024 * 1024)
#define GB(size) ( (size) * 1024 * 1024 * 1024)
int main(){
char *p;
p = (char *)malloc(MB(512));
memset(p, 'T', MB(512));
printf(".5 GB allocated...\n");
char *q;
q = (char *)malloc(MB(512));
memset(q, 'T', MB(512));
printf("1 GB allocated...\n");
printf("Sleeping...\n");
sleep(300);
}
Run Code Online (Sandbox Code Playgroud)
**编辑:我正在为我的操作系统使用CentOS 6.4(带有3.6.0内核),如果这有帮助的话.
Ser*_* L. 13
这是非常依赖OS /机器的.
在大多数操作系统中,既不分配RAM.它们都分配VM空间.它们使您的进程虚拟内存的某个范围有效使用.RAM通常在第一次写入时由OS稍后分配.在那之前,这些分配不使用RAM(除了将它们列为有效VM空间的页表之外).
如果要分配物理RAM,则必须使每个页面(sysconf(_SC_PAGESIZE)
给您系统页面大小)变脏.
在Linux中,您可以看到包含所有详细信息的VM映射/proc/self/smaps
.Rss
是你映射的常驻集合(驻留在RAM中多少),其他所有脏的都将被换出.所有非脏内存都可以使用,但在此之前不会存在.
你可以用所谓的东西弄脏所有页面
size_t mem_length;
char (*my_memory)[sysconf(_SC_PAGESIZE)] = mmap(
NULL
, mem_length
, PROT_READ | PROT_WRITE
, MAP_PRIVATE | MAP_ANONYMOUS
, -1
, 0
);
int i;
for (i = 0; i * sizeof(*my_memory) < mem_length; i++) {
my_memory[i][0] = 1;
}
Run Code Online (Sandbox Code Playgroud)
在某些实现中,这也可以通过将MAP_POPULATE
标志传递给mmap
,但是(取决于您的系统)它可能会失败mmap
,ENOMEM
如果您尝试映射更多,那么您有RAM可用.
理论和实践在这里有很大不同.从理论上讲,它既不分配mmap
也不malloc
分配实际的RAM,但实际上它们也是如此
mmap
将分配RAM来存储虚拟内存区域数据结构(VMA).如果mmap
与要映射的实际文件一起使用,它将(除非明确说明不同)进一步分配几页RAM以预取映射文件的内容.
除此之外,它只保留地址空间,RAM将在第一次访问时分配.
malloc
类似地,通过告诉操作系统通过sbrk
或者mmap
它想要管理一些(通常比您请求的大得多)的地址空间区域,仅在逻辑上保留进程的虚拟地址空间内的地址空间量.然后通过一些或多或少复杂的算法细分这个巨大的区域,最后保留一部分地址空间(正确对齐和舍入)供您使用,并返回指向它的指针.
但是: malloc
还需要在某处存储一些额外的信息,否则以后就不可能free
完成它的工作.free
除起始地址外,至少需要知道已分配块的大小.通常,malloc
因此秘密地分配一些额外的字节,这些字节紧接在你得到的地址之前 - 你不知道,它没有告诉你.
现在问题的关键在于,虽然理论上 malloc
并没有触及它管理的内存,也没有分配物理RAM,但实际上它确实如此.这确实会导致页面错误和内存页面被创建(即正在使用的RAM).
您可以在Linux下通过保持呼叫来malloc
监视并观察OOP杀手爆炸您的进程不存在,因为系统耗尽物理RAM,实际上应该有足够的剩余.