虚拟内存

内存分段

段选因子和段内偏移量

  • 段选因子主要是段号和特权标志位

导致内存碎片- 内存外部碎片,为了解决外部内存碎片,需要内存交换,导致的效率是非常低的

内存分页

主要是通过页表,页表存储在内存中,MMU内存管理单元进行转换

  • 内存分页会有内部内存碎片的问题
  • 同时存在扇入和扇出机制

单级页表导致的空间浪费可以通过多级页表解决。

同时通过使用TLB 页表缓存可以实现时间的优化

内存分页

缺页异常

分配的堆

img
  • 新申请的内存第一次被访问的时候
  • 内存访问在非法区
  • 代码段区域执行的时候发生缺页说明没有从磁盘加载代码段,发生缺页异常

malloc 分配内存

  • 小对象 brk 如果用户分配的内存小于 128 KB,则通过 brk() 申请内存; free掉不会归还给操作系统

    但是可能会导致内存碎片 甚至导致内存泄漏

img

  • 大对象 mmap 如果用户分配的内存大于 128 KB,则通过 mmap() 申请内存;free掉会马上归还给操作系统

    但是每一次都会发生系统调用 访问的时候都会发生缺页中断

img

内存满了

  • 后台内存回收
  • 直接内存回收
  • 都不能满足的话发生OOM机制

回收的时候主要是回收的文件页(io操作 把脏页写进磁盘,干净的直接释放掉),匿名页(通过swap机制扇入到硬盘) 都是基于lru算法 的变种 也就是两个双向链表

申请过量内存

  • 在 32 位操作系统,因为进程理论上最大能申请 3 GB 大小的虚拟内存,所以直接申请 8G 内存,会申请失败。

  • 在 64位 位操作系统,因为进程理论上最大能申请 128 TB 大小的虚拟内存,即使物理内存只有 4GB,申请 8G 内存也是没问题,因为申请的内存是虚拟内存。

    如果这块虚拟内存被访问了,要看系统有没有 Swap 分区:

    • 如果没有 Swap 分区,因为物理空间不够,进程会被操作系统杀掉,原因是 OOM(内存溢出);
    • 如果有 Swap 分区,即使物理内存只有 4GB,程序也能正常使用 8GB 的内存,进程可以正常运行;