关于内存分配,Cmalloc/calloc依赖Linuxmmap/malloc还是相反?
About memory allocation, does C malloc/calloc depends on Linux mmap/malloc or the opposite?
据我所知,C有如下函数,如:malloc
、calloc
、realloc
,用于分配内存。而linux内核还有如下功能,如:malloc
、mmap
、kmalloc
、vmalloc
...分配内存。
我想知道最低功能是哪个。
如果你说,“Linux 内核是最底层的函数,你的 C 程序必须使用 Linux 内核分配内存”,那么 Linux 内核如何分配它自己的内存?
或者如果你说,“Linux内核是最底层的功能。”,那么当我在Linux系统中编写C程序和运行时,分配内存,我应该通过系统调用。
希望得到解答
在linuxOS上,用户态程序使用的C函数malloc
、calloc
、realloc
在C库中实现,使用 mmap
系统调用处理映射到进程地址 space 的内存页面。 mmap
将虚拟内存页面与进程地址 space 中的地址相关联。当进程随后访问这些地址时,内核会将实际 RAM 映射到此虚拟 space。并非每次调用 malloc
都会映射内存页面,只有那些已经从系统请求的 space 不足的内存页面。
在内核space中,发生了类似的过程,但调用者可以要求立即映射RAM。
I want to know which is the lowest function.
user-levelmalloc
函数调用brk
或malloc
(取决于使用的库和Linux版本)。
... how does the Linux kernel allocate it's own memory?
在没有 MMU 的系统上这很容易:
假设我们的系统有 8 MB RAM,我们知道 RAM 的地址是 0x20000000 到 0x20800000。
内核包含一个数组,其中包含有关正在使用哪些页面的信息。假设“页面”的大小为 0x1000(这是具有 MMU 的 x86 系统中的页面大小)。
在旧 Linux 版本中,数组被命名为 mem_map
。数组中的每个元素对应一个内存“页面”。如果页面空闲,则为零。
系统启动时,内核自己初始化这个数组(将初始值写入数组)。
如果内核需要一页内存,它会在数组中搜索值为0 的元素。假设mem_map[0x123]
为0。内核现在设置mem_map[0x123]=1;
。 mem_map[0x123]
对应地址0x20123000
,所以内核在地址0x20123000
.
“分配”了一些内存
如果内核想要“释放”地址 0x20234000
处的一些内存,它只需设置 mem_map[0x234]=0;
.
在有MMU的系统上,稍微复杂一点,原理是一样的
据我所知,C有如下函数,如:malloc
、calloc
、realloc
,用于分配内存。而linux内核还有如下功能,如:malloc
、mmap
、kmalloc
、vmalloc
...分配内存。
我想知道最低功能是哪个。 如果你说,“Linux 内核是最底层的函数,你的 C 程序必须使用 Linux 内核分配内存”,那么 Linux 内核如何分配它自己的内存?
或者如果你说,“Linux内核是最底层的功能。”,那么当我在Linux系统中编写C程序和运行时,分配内存,我应该通过系统调用。
希望得到解答
在linuxOS上,用户态程序使用的C函数malloc
、calloc
、realloc
在C库中实现,使用 mmap
系统调用处理映射到进程地址 space 的内存页面。 mmap
将虚拟内存页面与进程地址 space 中的地址相关联。当进程随后访问这些地址时,内核会将实际 RAM 映射到此虚拟 space。并非每次调用 malloc
都会映射内存页面,只有那些已经从系统请求的 space 不足的内存页面。
在内核space中,发生了类似的过程,但调用者可以要求立即映射RAM。
I want to know which is the lowest function.
user-levelmalloc
函数调用brk
或malloc
(取决于使用的库和Linux版本)。
... how does the Linux kernel allocate it's own memory?
在没有 MMU 的系统上这很容易:
假设我们的系统有 8 MB RAM,我们知道 RAM 的地址是 0x20000000 到 0x20800000。
内核包含一个数组,其中包含有关正在使用哪些页面的信息。假设“页面”的大小为 0x1000(这是具有 MMU 的 x86 系统中的页面大小)。
在旧 Linux 版本中,数组被命名为 mem_map
。数组中的每个元素对应一个内存“页面”。如果页面空闲,则为零。
系统启动时,内核自己初始化这个数组(将初始值写入数组)。
如果内核需要一页内存,它会在数组中搜索值为0 的元素。假设mem_map[0x123]
为0。内核现在设置mem_map[0x123]=1;
。 mem_map[0x123]
对应地址0x20123000
,所以内核在地址0x20123000
.
如果内核想要“释放”地址 0x20234000
处的一些内存,它只需设置 mem_map[0x234]=0;
.
在有MMU的系统上,稍微复杂一点,原理是一样的