用一只麻雀来观察Linux内存分配惰性策略

结论先行

我们知道现代的计算机系统,通常分为虚存和物理内存。其中虚存和物理内存之间存在地址映射。

原则上机器的物理内存是宝贵的,所以,Linux使用懒惰的策略来进行分配物理内存,直到虚存被真实使用到!

实验设计

  • malloc来申请内存

仅体现为虚存的增长

  • malloc申请的内存进行逐字节写入访问

造成物理内存被依次分配出来,体现出阶梯状

观察手段

# notice the VIRT RES %MEM cols
top -p $(pidof a.out)

代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 

void readAnyKey()
{
  int c;
  while ((c = getchar()) != '\n' && c != EOF); 	
}

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");
  readAnyKey();
  
  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);
  
  free(pbBigMem);
  printf("You can see the program's VIRT&RES statistics decreased after big memroy is freed\n"
         "Enter any key to exit ...\n");
  readAnyKey();
  
  printf("\n\nExit from program !\n");
  return 0;
}

对内存分配器设计的潜在影响

Linux下,如果您申请一个大块内存池,作为管理器的管理空间,因为物理内存并没有被真实分配,在归还给管理器内存时,关于可用内存的管理将存在不同的策略设计。

  • 如果将归还的内存放置到管理器可用列表尾部,将会导致内存空间整个被真实访问,从而强迫管理器的整个空间占用了物理内存空间。

  • 如果将归还内存放置在可用列表头部,则内存被重复利用的可能性非常大,在不同的使用场景,管理器将倾向于使用少量的物理内存。

后记

  • 试验虚拟内存从高到低访问,以及从低到高的逐字节访问现象相同,RES占用逐渐增大
  • 对内存块free后的统计观察,亦发现VIRT&RES统计的明显变化,特别是大的内存块

Linux内存管理相当复杂,具体问题还需具体分析对待,这里演示的仅是一般原则

你可能感兴趣的:(c&c++技术,linux,物理内存分配,惰性策略)