当前位置:首页 > 内存 > 正文

malloc内存分配在哪里

  • 内存
  • 2024-06-04 01:15:37
  • 7227

一、内存分配(malloc)的过程

[TOC]

malloc、mmap等内存分配函数只分配进程的虚拟地址空间,并不分配实际的物理内存。当进程访问未映射的虚拟内存时,会自动触发页错误中断。

在需要分页的系统上,可以通过查询页表的当前状态位来检查当前页是否在内存中,如果没有,可以从内存地址读取缺失的页页表外部。例如,映射文件mmap.

使用ps-omajflt、minflt-Cprogram命令查看。

majflt表示majorfault(需要读盘),中文名称为majorfailure,minflt表示minorfault(不需要读盘),中文名称为minorfault。

这两个值代表自进程启动以来发生的页面错误的数量。

当进程发生页面错误时,该进程将陷入内核模式并执行以下操作:

如果在步骤3中需要读取磁盘,则此页面故障中断为majflt,否则为minflt。

从操作系统的角度来看,进程分配内存有两种方式,由两个系统调用完成:brk和mmap(不考虑共享内存)。

两种方法共享虚拟内存,不共享物理内存。当它第一次在给定的虚拟地址空间中打开时,会发生页面错误。

C标准库中提供了malloc/free函数来分配和释放内存,这两个函数的下层是通过brk、mmap、munmap等系统调用来实现的。

如果malloc小于128k内存,则使用brk分配内存,并将_edata推到更高的地址。

对于malloc大于128k内存,使用mmap分配内存并查找。堆和栈之间分配的一部分空闲内存(对应独立内存,初始化为0)

Mmap的内存释放在上节brk的内存释放中介绍过

由于brkheap不能直接释放,为什么不使用mmap分配,munmap直接释放呢?
实际上,进程向操作系统申请和释放地址空间所使用的sbrk/mmap/munmap接口都是系统调用,频繁的系统调用是比较常见的。另外,一旦mmap所需的内存为munmap,重新申请会产生更多的缺页中断。例如,使用mmap分配1M空间,第一次调用会产生大量缺页中断(1M/4K次),使用munmap重新分配1M空间时,会产生大量缺页中断脸)。再次。页错误中断是一种内核行为,在内核模式下会导致CPU消耗较高。另外,如果使用mmap来分配小内存,这会导致更多的地址空间碎片和更高的内核管理负载。
同时,堆是连续的空间,堆中的碎片不会返回给操作系统,如果碎片可以重用,再次访问内存可能不需要任何系统调用和页错误中断。,这将大大降低CPU的消耗。因此,glibc的malloc实现充分考虑了brk和mmap行为上的差异、优缺点。默认情况下,在使用mmap获取地址空间之前会分配一大块内存(128k)mallopt(M_MMAP_THRESHOLD,)这个临界值。