什么时候为进程分配内存 什么是内存

如何检查一个进程因缺页而中断的次数?
使用ps -o majflt,minflt -C程序命令查看 。
Majflt代表重大失误,中文名是大失误 , minflt代表小失误,中文名是小失误 。
这两个值表示自进程启动以来在进程中发生的缺页中断的数量 。
页面中断后执行了哪些操作?
当一个进程因缺页而中断时 , 该进程将进入内核状态 , 并执行以下操作:1 .检查要访问的虚拟地址是否合法;2.查找/分配物理页面;3.填写物理页面的内容(读取磁盘 , 或者直接设置为0,或者什么都不做);4.建立映射关系(虚拟地址到物理地址) , 重新执行缺页中断的指令 。如果在步骤3中需要读取磁盘,这一次它丢失了 。
内存分配原则
从操作系统的角度来看,进程分配内存有两种方式,由两个系统调用完成:brk和mmap(不考虑共享内存) 。
1.brk是推数据段的最高地址指针_edata( 。数据)到更高的地址;
2.mmap就是在进程的虚拟地址空中找一块空空闲的虚拟内存(堆和栈的中间,称为文件映射区) 。
在这两种方式中,都分配了虚拟内存 , 但没有分配物理内存 。第一次访问分配的虚拟地址空时 , 发生页面错误,操作系统负责分配物理内存 , 然后建立虚拟内存和物理内存的映射关系 。在标准C库中,提供了malloc/free函数来分配和释放内存 。这两个函数的底层是通过brk、mmap、munmap等系统调用来实现的 。
这里有一个例子来说明内存分配的原理:
1.对于malloc小于128k的内存,使用brk分配内存,push _edata到高位地址(只分配虚拟空 , 不对应物理内存(所以不初始化) 。第一次读写数据时,内核会因为缺页而中断,之后内核会分配相应的物理内存,然后建立虚拟地址空的映射关系 。
1.当进程开始时,其(虚拟)内存空的初始布局如图1所示 。
其中mmap内存映射文件在堆和栈中间(如libc-2.2.93.so,其他数据文件等 。),为了简单起见,省略了内存映射文件 。
_edata指针(在glibc中定义)指向数据段的最高地址 。2.在进程调用A=malloc(30K)之后 , memory 空 room如图2所示:
malloc函数会调用brk系统调用,将_edata指针推至高地址30K,完成虚拟内存分配 。
你可能会问:只放_edata 30K就完成内存分配了?
事实是 , _edata 30K只完成了虚拟地址的分配,仍然没有这个内存A对应的物理页,当进程第一次读写这个内存A时,发生了缺页中断 。此时内核分配的是这个内存A对应的物理页,也就是说,如果内容A是用malloc分配的,然后一直不访问,那么A对应的物理页就不会被分配 。3.在进程调用B=malloc(40K)之后,memory 空 room如图3所示 。
C/C Linux服务器架构师需要学习后台私有信息“信息”(信息包括C/C、Linux、golang技术、Nginx、ZeroMQ、MySQL、Redis、fastdfs、MongoDB、ZK、流媒体、CDN、P2P、K8S、Docker、TCP/IP、协成、DPDK、ffmpeg等).
二 。对于malloc大于128k的内存,使用mmap分配内存 , 在堆和栈之间找一块空的空闲内存来分配(对应独立内存,初始化为0) , 如下图:
4.在进程调用C=malloc(200K)之后,memory 空 room如图4所示:
默认情况下,malloc函数分配内存 。如果请求的内存大于128K(可通过M_MMAP_THRESHOLD选项进行调整),它不会推送_edata指针,而是使用MMAP系统调用从堆和堆栈中间分配一个虚拟内存 。
这主要是因为:
brk分配的内存需要等到高地址内存释放后才能释放(比如B释放前,A释放不了 , 这就是内存碎片的原因 。见下图何时收紧) , 而mmap分配的内存可以单独释放 。
当然也有其他的优缺点 。更具体地说 , 感兴趣的同学可以阅读glibc中的malloc代码 。5.进程调用D=malloc(100K)后,内存空空间如图5所示;6.进程调用free(C)后,C对应的虚拟内存和物理内存一起被释放 。
7.该过程调用free(B)后,如图7所示:
B对应的虚拟内存和物理内存都没有释放,因为只有一个_edata指针 。如果往后推 , D的内存怎么办?
当然,内存B可以重复使用 。如果此时又来了一个40K的请求,malloc很可能会返回内存B. 8 。该过程调用free(D)后,如图8所示:
而b和d连接起来形成一个140K 空的空闲内存 。
9.默认情况下:
当最高地址空之间的空空闲内存超过128K(可通过M_TRIM_THRESHOLD选项调整)时,执行内存紧缩操作(TRIM) 。在free的最后一步 , 发现最高地址空的空闲内存超过了128K,于是内存变紧,如图9所示 。了解了内存分配的原理之后 , 再来看一个现象:现象 。

推荐阅读