1.为什么要有内存管理?
首先,无论是单片机还是计算机,在进行运算时都需要从内存中获取数据资源,如何去找到正确的数据地址,这就需要内存管理。
其次,计算机相比于单片机,可以同时运行的程序(进程)更多,进程中的变量、程序都需要访问内存中的物理地址。但是物理地址是唯一的,要想保证物理地址不冲突,就设计出了虚拟内存(类似于相对地址)来方便内存管理,由内存管理单元负责将虚拟地址映射到真实物理地址。
2.虚拟内存有什么用?
1.虚拟内存可以扩大计算机的内存空间。
2.每个进程都有自己的页表,所有其虚拟内存空间是独立的,这解决了多进程地址冲突的问题。
3.页表还有标记属性。
3.内存分段是什么?会导致什么问题?
内存分段就是内存管理中的一种映射模式,它通过段基地址和偏移量来确定分段位置。
内存分段会到导致:
1.外部内存碎片(进程间内存碎片),即进程A、进程B、进程C运行时,进程B退出但是进程D占用空间比进程B大,导致进程D进不来,进程B原有空间浪费的问题。
2.内存交换效率低。面对问题1,进程C需要从内存移动到硬盘,再重新写回进程A旁边,这样才能给进程D腾出空间,这导致了进程C的频繁读写,浪费了资源。
4.内存分页是什么?会导致什么问题?
内存分页也是内存管理中的一种映射模式,它通过页表(页号+页内偏移量)来映射。
由于内存分页的大小是固定的,因此一个进程不会出现和另一个进程之间的内存碎片,但是会产生页内的内存碎片。
操作系统可以运行很多内存,每个进程都需要一个页表,非常占用空间。该问题通过多级页表解决,但是从虚拟地址到物理地址的转换就多了几道转换工序,降低了地址转换速度。因此又加入了转址旁路缓存、页表缓存用来记录常访问的页表。
5.Linux下内存布局?
32位下(4G)
从地址低位到地址高位分别是:3G用户空间,1G内核空间。(靠近地址0的区域有一小段不可访问)
64位下
地址低位是128T用户空间,地址高位是128T内核空间,两者中间还有一部分空白。
6.malloc()是如何分配内存空间的?
如果用户分配的内存小于128KB,就通过brk()向堆区申请空间;如果大于128kb就通过mmap()向文件区域申请空间。
实际上malloc()申请了132kb的字节的虚拟空间。
7.free函数怎么知道释放多大的空间?
利用free释放内存时,brk()并不会把内存归还给操作系统,而是等待下次复用,而通过mmap()申请的内存会归还。
在malloc()函数中有16字节用于保存内存块信息。
8.内存分配的过程是怎样的?
malloc()申请虚拟内存-->应用程序读写该内存-->页表没有物理内存,产生缺页中断-->进程由用户态转为内核态,将缺页中断交给缺页中断函数处理-->缺页中断函数查看是否有空闲的物理内存?如果有直接建立虚拟内存物理映射,否则依次进行如下优先级回收1.后台内存回收kswapd异步回收 2.直接内存回收,同步进行,并阻塞进程的执行。3.触发OOM,选择一个占用物理内存较高的进程杀死,直到物理内存满足。