操作系统专栏1-内存管理from 小林coding

news2024/9/27 17:24:39

操作系统专栏1-内存管理

  • 虚拟地址
    • 内存管理方案
    • 分段
    • 分页
      • 页表
        • 单级页表
        • 多级页表
        • TLB
    • 段页式内存管理
    • Linux内存管理
  • malloc工作方式
  • 操作系统内存回收
    • 回收的内存种类
  • 预读失败和缓存污染问题
    • 预读机制
    • 预读机制失效
    • 解决方案
    • 缓存污染
  • 内核对虚拟内存的表示
  • 内核对内核空间的表示
    • 直接映射区
    • vmalloc映射区
    • 永久映射区
    • 固定映射区
    • 临时映射区

虚拟地址

首先第一个问题,虚拟地址为什么要存在呢,原因其实很简单,隔离开多个进程之间的地址空间,让每个进程都认为自己拥有一块完整的物理空间,并且提供大的逻辑内存供进程使用,虚拟地址是现代操作系统进行内存管理的基石

内存管理方案

分段

程序的内存空间由多个段组成,代码段,数据段,堆段和栈段组成,用分段的方式将这些段隔离开来
在这里插入图片描述
那么分段的方式有什么缺点呢,主要两点外部内存碎片交换效率
外部碎片的产生
外部内存碎片的解决方案为内存交换,将音乐程序占用的256MB先换出到磁盘上,然后读回到内存中(实际上就是换了位置,紧邻着存)Linux系统中的SWAP分区就是干这个的

分页

分段的弊端在上节描述,为了减少内存换进换出的装载量,出现了分页,分页就是把整个内存区域切分成固定大小的片(一般为4KB).示意图如下
在这里插入图片描述分页访问在发现虚拟地址在页表中查询不到时,产生一个缺页异常,操作系统分配好内存空间之后,更新页表,返回进程继续运行,页与页之间是紧密排列的,所以不会有外部碎片,但是引入了内部碎片,而且页的大小固定,换入换出的开销也变得可以接受了

页表

页表实际上就是虚拟地址和物理地址的一个映射关系

单级页表

单级页表存在一个页表存储空间占用过大的问题,假设目标机为32位机,虚拟内存共有4GB,那么共有4GB/4KB = 2^20个页,每个页表项4B,那么共需4MB的空间来存储页表,注意,每个进程有自己的页表,那么100个进程需要400MB,1000个进程就将4GB全部占完了

多级页表

解决上述的问题,采用多级页表,多级页表的实质就是只在一级页表页实际用到的情况下才创建2-n级的页表,

在这里插入图片描述

TLB

多级页表实际上是一种时间换空间的方案,为了加速虚拟地址到物理地址的转换,TLB被提出,TLB存在于CPU中,存放的是最近访问的页表

段页式内存管理

段页式是操作系统常用的内存管理方式,实现方式为,先把程序的内存空间分段,再对这些段分页
在这里插入图片描述

Linux内存管理

Linux主要是页式内存管理,段内存被Linux给绕了过去,每个段都是从0地址开始的4GB地址空间
在这里插入图片描述
Linux的内核空间是每个进程共享的
在这里插入图片描述
其中

  • 代码段:存放二进制可执行代码
  • 数据段:已初始化的静态常量和全局变量
  • BSS:为初始化的静态变量和全局变量
  • 堆段:动态分配的内存,地址空间从低到高增长
  • 文件映射段:动态库,共享内存
  • 栈段:局部变量和函数调用的上下文,栈大小固定,大小一般为8MB

malloc工作方式

malloc申请内存有两种方式

  • 小于128KB,brk()系统调用在堆上分配内存
  • 大于128KB,mmap()系统在文件映射区分配内存

这两种方式的区别在于

  • brk()方式申请的内存,在free释放内存时,并不会归还给操作系统,而是缓存在内存池中,待下次使用
  • mmap()申请的内存,free释放时,会归还给操作系统

操作系统内存回收

当没有空闲的物理内存可用时,内核就会开始进行回收内存的工作,回收方式有两种,直接内存回收和后台内存回收

  • 后台内存回收:在物理内存紧张时,唤醒kswapd内核线程,这个线程是异步的,不会阻塞进程的执行
  • 直接内存回收,当后台异步回收跟不上进程内存的申请速度,就会开始直接回收,这个回收过程是同步的,会阻塞进程的执行
    直接回收后,若空闲的物理内存仍然无法满足物理内存的申请,那么内核就会使用OOM机制(直接杀掉内存占用高的进程)
    在这里插入图片描述

回收的内存种类

能被回收的内存有两类,分别是文件页和匿名页

  • 文件页:内核缓存的磁盘数据和内核缓存的文件数据都可以被称为文件页,分为干净页和脏页,干净页指没有被修改过的,直接释放即可,脏页需要先写到磁盘后才能释放
  • 匿名页:这部分内存没有实际上的载体(没有对应的磁盘文件),堆和栈都属于这种页,这种页的回收方式是通过Linux的Swap机制先写到磁盘中

 实际上由于文件页回收有可能是干净页,这个时候不需要磁盘IO,所以文件页的回收往往性能高
 回收内存的算法为LRU算法,在linux的回收算法中,维护两个链表,active和inactive列表,active列表存放最近被访问过的活跃内存页,inactive列表存放非活跃的页,回收时,优先访问不活跃的内存

预读失败和缓存污染问题

预读机制

当操作系统试图磁盘读时,会把临近的数据也读到内存中,以备之后访问

预读机制失效

提前被加载的页,如果以后不被访问,还可能挤掉热点数据页,大大降低了缓存命中率

解决方案

  • Linux解决方案是分为了两个LRU链表,活跃LRU和非活跃LRU,这两个LRU互相独立,互不干扰
  • MySQL的InnoDB在LRU列表上划分两个区域young区域和old区域

缓存污染

上面的方案如果数据被加载并被读了一次,还是会挤走热点数据,解决方案是提升加入活跃LRU的门槛

内核对虚拟内存的表示

主要是通过mm_struct这个结构体表示的
在这里插入图片描述
在这里插入图片描述

内核对内核空间的表示

通过TASK_SIZE将进程的虚拟内存空间和内核内存空间分割开来之后,在32位下0xC000000 - 0xFFFF FFFF这段空间的分配如下
在这里插入图片描述

直接映射区

其中ZONE_NORMAL和ZONE_DMA共同构成了直接映射区,直接映射区占896M会直接映射到物理内存的前896M内存空间中,当进程被创建完毕,在内核运行的过程中,内核会为每一个进程设置一个内核栈,每个进程的掉用链存放在自己的内核栈中,每个内核栈大概占据2的页的内存空间

  • ZONE_DMA为DMA映射区,为16MB
  • ZONE_NORMAL存放上问所述的内核栈等信息

vmalloc映射区

vmalloc区分配的内存在虚拟内存上连续,而在物理内存上不连续

永久映射区

虚拟地址于物理地址建立长期的映射关系

固定映射区

虚拟地址固定,但是物理地址不固定(指针常量)

临时映射区

在中断处理等时使用的救急内存

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/809143.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一个字符驱动示例 -- 微秒级别周期 反转GPIO

仅作为自我记录的一个demo 本次GPIO以微妙级别频率的反转实验有以下几个启示: 一开始在应用层做延时,来实现2微妙周期,占空比50%的GPIO反转,发现波形的频率一直上不去,只能在25hz徘徊,后来索性去掉延时&am…

96. Python基础教程:多个异常的处理方法(2个except语句)

【目录】 文章目录 96. Python基础教程:多个异常的处理方法(2个except语句)1. 2个except语句练习-分苹果2. except (异常类型1,异常类型2) as 别名 【正文】 96. Python基础教程:多个异常的处理方法(2个except语句) 1. 2个except语句练习-分苹果 任务目标写一个模拟幼儿园老师…

TCP网络通信编程之netstat

【netstat指令】 【说明】 (1)Listening 表示某个端口在监听 (2)如果有一个外部程序(客户端)连接到该端口,就会显示一条连接信息 (3)指令netstat -anb 可以参看是那个…

分库分表之基于Shardingjdbc+docker+mysql主从架构实现读写分离(二)

说明:如果实现了docker部署mysql并完成主从复制的话再继续,本篇文章主要说明springboot配置实现Shardingjdbc进行读写分离操作。 如果没实现docker部署mysql实现主从架构的话点击我 Shardingjdbc配置介绍(版本:5.3.2)…

04-树6 Complete Binary Search Tree(C++)

思路 先排序&#xff08;冒泡排序&#xff09; 用数组建一棵空树&#xff08;用数组&#xff0c;填好左右儿子&#xff09; 中序遍历填数&#xff08; Tree::travIn() &#xff09; 顺序输出即为层次遍历&#xff08; Tree::travLevel() &#xff09; code # include <…

三步问题(力扣)n种解法 JAVA

目录 题目&#xff1a;1、dfs:2、dfs 备忘录&#xff08;剪枝&#xff09;&#xff1a;&#xff08;1&#xff09;神器 HashMap 备忘录&#xff1a;&#xff08;2&#xff09;数组 memo 备忘录&#xff1a; 3、动态规划&#xff1a;4、利用 static 的储存功能&#xff1a;&…

C++ - stack 和 queue 模拟实现 -认识 deque 容器 容器适配器

stack模拟实现 用模版实现 链式栈 和 顺序栈 对于stack 的实现&#xff0c;有两种方式&#xff0c;一种是连续空间存储的顺序栈&#xff0c;一种是不连续空间存储的链式栈&#xff0c;在C当中如果要使用两种不同的栈的话&#xff0c;实现方式是不一样的&#xff0c;他们的底层逻…

Transformer背景介绍

目录 Transformer的诞生Transformer的优势Transformer的市场 Transformer的诞生 论文地址 Transformer的优势 Transformer的市场

【MySQL】事务管理

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《零基础入门MySQL》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录 &#x1f449;CU…

使用mediapipe训练手指数字识别

mediapipe手指数字识别 本文是从0开始创建一个识别手势的机器学习模型&#xff0c;为了识别手势&#xff0c;采用mediapipe模型&#xff0c;这个模型会返回手指的位置&#xff0c;之后再通过训练一个模型将这些位置分类得到手势 一、导入依赖 import cv2 import numpy as np…

分库分表之基于Shardingjdbc+docker+mysql主从架构实现读写分离(一)

说明&#xff1a;请先自行安装好docker再来看本篇文章&#xff0c;本篇文章主要实现通过使用docker部署mysql实现读写分离&#xff0c;并连接数据库测试。第二篇将实现使用Shardingjdbc实现springboot的读写分离实现。 基于Docker去创建Mysql的主从架构 #创建主从数据库文件夹…

小黑子—JavaWeb:第四章 Request与Response

JavaWeb入门4.0 1. Request(请求)& Response (响应)2. Request2.1 Request 继承体系2.2 Request 获取请求数据2.2.1 通用方式获取请求参数2.2.2 IDEA模板创建Servlet2.2.3 请求参数中文乱码处理2.2.3 - I POST解决方案2.2.3 - II GET解决方案 2.3 Request 请求转发 3. Resp…

常见网关对比

常见网关对比 目前常见的开源网关大致上按照语言分类有如下几类&#xff1a; Nginxlua &#xff1a;OpenResty、Kong、Orange、Abtesting gateway 等 Java &#xff1a;Zuul/Zuul2、Spring Cloud Gateway、Kaazing KWG、gravitee、Dromara soul 等 Go &#xff1a;Janus、fa…

简单学会MyBatis原生API注解

&#x1f600;前言 本篇博文是关于MyBatis原生API&注解的使用&#xff0c;希望能够帮助到你&#x1f60a; &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家&#xff0c;您…

2023深圳杯数学建模B题

B题 电子资源版权保护问题 版权又称著作权&#xff0c;包括发表权、署名权、修改权、保护作品完整权、复制权、发行权、出租权、展览权、表演权、放映权、广播权、信息网络传播权、摄制权、改编权、翻译权、汇编权及应当由著作权人享有的其他权利。 在计算机网络广泛应用的今…

39.手机导航

手机导航 html部分 <div class"phone"><div class"content"><img class"active" src"./static/20180529205331_yhGyf.jpeg" alt"" srcset""><img src"./static/20190214214253_hsjqw…

基于 ThinkPHP 5.1(稳定版本) 开发wms 进销存系统源码

基于ThinkPHP 5.1&#xff08;LTS版本&#xff09;开发的WMS进销存系统源码 管理员账号密码&#xff1a;admin 一、项目简介 这个系统是一个基于ThinkPHP框架的WMS进销存系统。 二、实现功能 控制台 – 权限管理&#xff08;用户管理、角色管理、节点管理&#xff09; – 订…

BUUCTF——reverse3 适合新手的关于base64加密算法代码的分析

作为一个逆向小白&#xff0c;学了点加密算法就来BUU找点乐子&#xff0c;前7题蛮简单的&#xff0c;然后做到了reverse3&#xff0c;典型的base64加密算法&#xff0c;让我折腾了好久&#xff0c;写篇博客记录一下 顺便说下很多博客并没有对这里的加密算法进行代码上的分析&a…

秋招备战笔试Day1

目录 单选 1. 在 Java 中&#xff0c;存放字符串常量的对象属于&#xff08; &#xff09;类对象。 2.已知如下类定义&#xff1a; 如下哪句可以正确地加入子类中&#xff1f; 3. 下列选项中属于面向对象编程主要特征的是&#xff08;&#xff09; 4.关于下列程序段的输出结…

并发编程可能出现的核心问题

2.1非可见性 如果主内存里有个静态变量flagfalse&#xff0c;然后线程A和B在工作内存都需要操作flag&#xff0c;线程A是while(!false){}&#xff0c;而线程B将flag改为true&#xff0c;但是由于线程A和线程B之间工作内存互相不可见&#xff0c;线程A就会陷入死循环。 2.2指令…