当前位置:   article > 正文

malloc(1) 会分配多大的虚拟内存?_mallc(1) 实际申请的内存空间

mallc(1) 实际申请的内存空间

malloc() 分配的是虚拟内存

如果分配后的虚拟内存没有被访问的话,虚拟内存是不会映射到物理内存的,这样就不会占用物理内存了。

只有在访问已分配的虚拟地址空间的时候,操作系统通过查找页表,发现虚拟内存对应的页没有在物理内存中,就会触发缺页中断,然后操作系统会建立虚拟内存和物理内存之间的映射关系。

malloc() 在分配内存的时候,并不是老老实实按用户预期申请的字节数来分配内存空间大小,而是会预分配更大的空间作为内存池

  1. #include <stdio.h>
  2. #include <malloc.h>
  3. int main() {
  4. printf("使用cat /proc/%d/maps查看内存分配\n",getpid());
  5. //申请1字节的内存
  6. void *addr = malloc(1);
  7. printf("此1字节的内存起始地址:%x\n", addr);
  8. printf("使用cat /proc/%d/maps查看内存分配\n",getpid());
  9. //将程序阻塞,当输入任意字符时才往下执行
  10. getchar();
  11. //释放内存
  12. free(addr);
  13. printf("释放了1字节的内存,但heap堆并不会释放\n");
  14. getchar();
  15. return 0;
  16. }

  

 

大约分配16KB ,为什么打印的地址比mmap映射的地址多10个Byte?

 是因为free()调用的时候,因为分配地址的时候就多了10Byte的头部用来描述分配到内容,所以free不需要额外的地址。

free 释放内存,会归还给操作系统

 

这是因为与其把这 1 字节释放给操作系统,不如先缓存着放进 malloc 的内存池里,当进程再次申请 1 字节的内存时就可以直接复用,这样速度快了很多。

当然,当进程退出后,操作系统就会回收进程的所有资源。

 

  • malloc 通过 brk() 方式申请的内存,free 释放内存的时候,并不会把内存归还给操作系统,而是缓存在 malloc 的内存池中,待下次使用
  • malloc 通过 mmap() 方式申请的内存,free 释放内存的时候,会把内存归还给操作系统,内存得到真正的释放

频繁通过 mmap 分配的内存话,不仅每次都会发生运行态的切换,还会发生缺页中断(在第一次访问虚拟地址后),这样会导致 CPU 消耗较大

通过 brk() 系统调用在堆空间申请内存的时候,由于堆空间是连续的,所以直接预分配更大的内存来作为内存池,当内存释放的时候,就缓存在内存池中。

等下次在申请内存的时候,就直接从内存池取出对应的内存块就行了,而且可能这个内存块的虚拟地址与物理地址的映射关系还存在,这样不仅减少了系统调用的次数,也减少了缺页中断的次数,这将大大降低 CPU 的消耗。图片

 当执行 free() 函数时,free 会对传入进来的内存地址向左偏移 16 字节,然后从这个 16 字节的分析出当前的内存块的大小,自然就知道要释放多大的内存

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/333325
推荐阅读
  

闽ICP备14008679号