为什么要有虚拟内存?
当物理内存不够用的时候,操作系统会通过内存交换技术将不常使用的内存换出到硬盘,等到需要的时候再加载回来。
内存分配的四种方式?
内存分段的存储管理方式:
这种方式下会将一个程序分成若干个逻辑分段,比如代码段,数据段,栈段,堆段。
分段分配的弊端:
内存碎片:内存碎片分为内部内存碎片和外部内存碎片。内存分段管理可以根据各个段的需要求分配对应大小的段,不会有内部内存碎片。外部内存碎片是由于多个段不能恰好使用所有的内存空间,产生了多个不连续的小块物理内存。内存交换就是用于解决这个问题的。
内存交换空间:位于硬盘空间,用于内存和硬盘空间的交换。
内存交换效率低:内存交换是将不常用的内存暂时移动到磁盘交换空间,给其他任务腾空间。
如果交换的是一个内存占用很大的程序,会出现较大的卡顿。
内存分页的存储管理方式:
分页的情况下会将虚拟内存和物理内存都划分成一段段固定大小的页,在linux中,一个页的大小是4kb。
分页如何解决外部内存碎片和内存交换效率低的问题?
内存分页是紧密排列的,不会有外部内存碎片。但是分配的最小单位是页,即使程序大小不足一页也会进行分配,所以会有内部内存碎片的问题。
如果内存空间不够,系统会使用LRU算法将内存页面释放。一次性写入磁盘的只有一个页或者是几个页,所以内存交换的效率比较高。
段页式的存储管理方式:
段页式的情况下会先将程序划分为多个有意义的段,比如代码段,数据段,栈段。然后每个段都划分为多个页。物理内存则是采用分页的方式。
Linux 内存布局
malloc 是如何分配内存的?
malloc() 分配的是物理内存吗?
不,malloc()分配的是虚拟内存。如果分配后的虚拟内存没有被访问的话,是不会映射到物理内存的。
malloc(1)会分配多大的虚拟内存?
反正不是一个字节大小的内存。
free 释放内存,会归还给操作系统吗?
不会,堆内存会保留这个内存到malloc的内存池里,等待下次申请直接复用。只有进程退出的时候才会回收所有资源。(只针对malloc通过brk()方式申请内存)
mmap在文件映射段分配的内存会被归还。
为什么不全部使用mmap分配内存?
总结下来就是两点原因。
减少用户态和内核态的切换。
减少缺页中断的发生次数。
为什么不全部使用brk()分配内存?
brk会有大量的内存碎片,所以默认大块的内存用mmap进行分配。
为什么free() 函数只传入一个内存地址,为什么能知道要释放多大的内存?
内存满了,会发生什么?
内存满了会发生OOM,在内存满之前应该会先尝试进行回收内存的工作。
哪些内存是可以被回收的?
文件页是那些硬盘里有的数据页。
匿名页则是程序运行生成的动态数据页,堆栈数据,这些需要通过内存交换持久化到磁盘中。
在内存大小4G的机器上申请8G的内存会怎么样?