携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第13天,点击查看活动详情
我们先来看下Linux进程中内存是怎么分布的。高地址是内核空间,低地址是用户空间。内核空间和用户空间的区别是进程在用户态的时候,只能访问用户空间,内核态的时候,权限比用户态高,可以访问到内核空间。用户空间中的程序文件段包含的是二进制可执行代码。已初始化数据段包含的是静态常量。未初始化数据段,包含的是未初始化的静态变量。堆段,包含的就是动态分配的内存,从低地址向上增长。文件映射段,包含的是动态库、共享内存。栈段,包含的是局部变量和函数调用上下文。我们在申请内存的时候经常使用的malloc有两种申请方式,如果分配的内存小于128KB,就通过brk()方式,如果大于128KB,就通过mmap()方式。其中brk()方式就是将堆顶的指针向高地址移动,来获取新的内存空间。Mmap()则是用匿名映射的方式在文件映射区申请了一块内存。这里值得注意的是,malloc申请的内存是虚拟内存,如果分配的虚拟内存没有被访问的话,这块虚拟内存并不会映射到物理内存,也不占用实际物理内存。只有在访问这块内存的时候,发现虚拟内存没有映射上实际物理内存,就会触发缺页中断,然后建立虚拟内存与实际物理内存的映射关系。Malloc通过brk()方式申请的内存在free释放内存的时候,不会将内存还给操作系统,而是缓存在malloc自己的内存池中,等待下次使用。Malloc通过mmap()方式申请的内存在free释放的时候,则会将内存还给操作系统,内存会得到真正的释放。