我们知道现代的计算机系统,通常分为虚存和物理内存。其中虚存和物理内存之间存在地址映射。
原则上机器的物理内存是宝贵的,所以,Linux
使用懒惰的策略
来进行分配物理内存,直到虚存被真实使用到!
malloc
来申请内存仅体现为虚存的增长
malloc
申请的内存进行逐字节写入访问造成物理内存被依次分配出来,体现出阶梯状
# notice the VIRT RES %MEM cols
top -p $(pidof a.out)
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include <stdint.h>
int main(int argc , char* argv[])
{
printf("Hello world!\n"
"To see the `top` command memory statistics!\n\n");
int sleeptime = 3;
if(argc > 1)
{
sleeptime = atoi(argv[1]);
}
printf("Using sleeptime: %d argument to watch the incresing RES(physical) statistic\n"
"But the VIRT statistic keeps unchanged after malloc\n\n", sleeptime);
printf("You can see the program's VIRT&RES&%%MEM statistics using `top` command\n\n"
"The initial VIRT&RES statistics must be small\n"
"Enter any key to continue to malloc a big memory area\n");
int c = getchar();
const size_t nBigSize = 1*1024*1024*1024;
char* const pbBigMem = malloc(nBigSize);
if(pbBigMem == NULL)
{
perror("Malloc a big memory");
return -1;
}
printf("\nThe VIRT statistic is changed after malloc\n");
char* const pbBigMemEnd = pbBigMem + nBigSize;
char* cursor = pbBigMem;
do
{
// Access the memory to cause the physical memory to be assigned
for(size_t i = 0; i < (100*1024*1024) && cursor < pbBigMemEnd; ++i, ++cursor)
{
// one by one
cursor[0] = (char)i;
}
printf("The RES statistic is changed after the memory is really scaned one by one, cursor: %p\n", cursor);
sleep(sleeptime);
}
while(cursor < pbBigMemEnd);
printf("\n\nExit from program !\n");
return 0;
}
在Linux
下,如果您申请一个大块内存池,作为管理器的管理空间,因为物理内存并没有被真实分配,在归还给管理器内存时,关于可用内存的管理将存在不同的策略设计。
如果将归还的内存放置到管理器可用列表尾部,将会导致内存空间整个被真实访问,从而强迫管理器的整个空间占用了物理内存空间。
如果将归还内存放置在可用列表头部,则内存被重复利用的可能性非常大,在不同的使用场景,管理器将倾向于使用少量的物理内存。