五:用户空间内存分配

目录

用户空间内存分配

mmap

malloc


用户空间内存分配

mmap

将内核空间直接映射到用户空间,省去从内核到用户空间的内存拷贝。

mmap的缺点

  1. mmap 使用时必须实现指定好内存映射的大小,因此 mmap 并不适合变长文件;
  2. mmap如果更新文件的操作很多,mmap 避免两态拷贝的优势就被摊还,最终还是落在了大量的脏页回写及由此引发的随机 I/O 上,所以在随机写很多的情况下,mmap 方式在效率上不一定会比带缓冲区的一般写快;
  3. 读/写小文件(例如 16K 以下的文件),mmap 与通过 read 系统调用相比有着更高的开销与延迟;同时 mmap 的刷盘由系统全权控制,但是在小数据量的情况下由应用本身手动控制更好;
  4. mmap 受限于操作系统内存大小:例如在 32-bits 的操作系统上,虚拟内存总大小也就 2GB,但由于 mmap 必须要在内存中找到一块连续的地址块,此时你就无法对 4GB 大小的文件完全进行 mmap,在这种情况下你必须分多块分别进行 mmap,但是此时地址内存地址已经不再连续,使用 mmap 的意义大打折扣,而且引入了额外的复杂性;

所以mmap 的适用场景实际上非常受限,在如下场合下可以选择使用 mmap 机制:

mmap 机制下多线程共享了同一物理内存空间。所以多线程的通信,共享内存时,mmap比较适合。

malloc

  • 方式一:通过 brk() 系统调用从堆分配内存
  • 方式二:通过 mmap() 系统调用在文件映射区域分配内存;

malloc() 源码里默认定义了一个阈值:

  • 如果用户分配的内存小于 128 KB,则通过 brk() 申请内存;
  • 如果用户分配的内存大于 128 KB,则通过 mmap() 申请内存;

malloc() 在分配内存的时候,并不是老老实实按用户预期申请的字节数来分配内存空间大小,而是会预分配更大的空间作为内存池。比如malloc(1)分配1字节的空间,但实际会分配更大的空间作为内存池。内存池通过在程序初始化时预分配一定数量的内存,将分配的内存块存放在内存池中,需要使用时直接从内存池中获取,不需要再向操作系统请求分配内存,从而避免了频繁的系统调用,提高了效率。free时,再将其重新放入内存池中,需要时就可以直接从内存池中取

对于 「malloc 申请的内存,free 释放内存会归还给操作系统吗?」这个问题,我们可以做个总结了:

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

猜你喜欢

转载自blog.csdn.net/qq_52353238/article/details/130217551
今日推荐