Linux内核相关知识点记录【内存管理】【进程调度】【异常调试】【锁】【kvm虚拟化】【内核启动】

2023-11-08

1、内存管理 怎么阐述自己的理解?
。硬件原理,分页机制原理
内核内存管理由MMU提供硬件支持,MMU实现虚实地址VA=>PA的转换以及权限检查,虚拟地址和物理地址之间的映射关系是页表机制,每一个页表项都保持物理地址页及其访问权限,页表机制和图书馆借书是一个原理,为什么要用多级页表呢?假设只有一级,类比成数组,用a【i】记录每一项,那么记录所有映射关系i=4GB/4KB=1000*1000项,显然不现实,线性数组查找效率低下,分级的好处就是把线性查找转换才二分法查找,所需时间是log 2^n,极大提高效率,这也就是内存管理使用树结构的原因,类比图书馆借书的例子:首先在电脑上查到书在 4楼-13巷 -5架-6层-100号,那么拿到这个地址去对应的楼层(一级页表),巷号(二级页表),架次(三级页表),层(4级页表),最后找到100这个编号的书(页内偏移)。
开启了mmu,那么只有mmu本身可以看到物理地址,CPU发出的都是虚拟地址.mmu的页表寄存器记录了页表本身保存在物理内存的位置。
每个进程都有4G的地址空间,0-3G是用户地址空间,3-4G是共享的内核地址空间,每个进程都有自己独立的页表,进程切换的时候,内核会把进程的页表地址填入MMU实现进程切换.这样就实现了各个进程地址空间隔离.
MMU如何实现内存权限保护?比如定义一个const 常量,那么C编译器就会把这个const常量链接到rodata(只读数据段),载入内存建立页表时被标记为readonly,MMU提供运行时检查,如果有人试图去写它,那么就会被MMU拦截发出segmentfault.实现了内存保护的机制.
TLB保存最频繁使用的页表数据,属于MMU的高速缓存.
物理内存划分区域: DMA zone, normal zone,highmem zone,
虚拟地址空间是指每个进程的0-4g虚拟地址空间,属于虚拟地址的概念,而低端、高端内存是属于物理内存的概念.
内核中物理内存的管理是由buudy算法实现,buddy以2的n次方对空闲内存进行管理,最分配粒度是1页,也就是4k,而slub算法是基于buddy算法的二次管理,用于分配更小的内存粒度。
。内存动态分配和释放,kmalloc,vmalloc,slub,buddy system的特点和关系.讲述用户空间malloc 1M内存后发生了什么?
从buddy拿到的内存都是以1页为单位粒度,而slub是从buddy拿一大块内存进行二次管理,以更小的分配粒度分配和回收,kmallc就是从slub拿内存,kmallc/kfree和buddy不是一样对应关系,执行kfree不一定还给buddy,具体什么时候还,是slub算法 决定,这样做的目的是为了应对频繁申请释放内存的场景对性能的影响.
kmalloc申请的内存是线性映射关系,适用于频繁申请释放且小块的内存,效率高,但是注意kmalloc可以休眠,特别是内存紧张得时候.
vmalloc申请的内存是非线性映射关系,是使用红黑树数据结构管理,用于申请大块的对物理内存没有连续要求的场景,优先从highmem区域拿,通过alloc_page从buddy拿内存.
malloc是libc的库函数,不是系统调用,libc库对申请的内存做二次管理,其最终是通过brk和mmap向内核要内存.malloc/free不是系统调用和内核不是一一对应关系.free后不一定还给内核,具体什么时候还,由libc算法决定,这是为了性能的考量,因为对物理内存频繁的申请释放对性能有影响.
malloc 1M内存的时候并没有真正拿到物理内存,只是将分配的连续VMA映射到一片清零的物理地址并标注为readonly,只有当有人去写这块VMA的时候,MMU执行地址转换检查权限发现是只读,会被MMU拦截而触发page fault,但是内核检查到当前的地址权限是R+W,发现是malloc导致的page fault,然后分配物理内存页,改写权限,此刻真正拿到物理内存。而且是边写边拿.这就是所谓内核分配内存的lazzy性,这样做的目的是因为内核无法控制应用程序的行为,尽量防止申请了不用的浪费情况.
内核不信任应用程序只相信内核本身。lazzy只针对应用程序,不针对内核,内核调用kmalloc或者vmalloc就是立即拿到内存.
。进程的虚拟内存VMA(virtual memory areas)
VMA区域存在用户空间,可以是独占的也可以是共享的,一个进程拥有多个VMA,零散分别在0-3G的地址空间,每一个进程的代码段,数据段,堆都是一个VMA实例,
查看vma的方法:
/proc/pid/maps 、 /proc/pid/smaps
page fault的可能性:
a: 动态内存分配,写时拷贝,属于次要的page fault,因为不需要去硬盘load数据,开销小。
b: 进程访问不可读写的非法地址,会被MMU拦截,内核发出segment fault信号,导致oops.
c: 进程访问VMA区域,但是权限不对,比如代码段权限是R+X,但是你尝试去写,也会和上面一样的结局
d: 进程访问VMA区域,权限检查通过,但是需要从硬盘load数据到内存,这种属于大开销,所谓主要的page fault,比如代码段首次被载入内存的时候,这也就是为什么第一次启动进程比第二次慢的原因.(内存大手机跑得更流程原因之一)
VSS - Virtual Set Size 虚拟耗用内存
RSS - Resident Set Size 实际使用物理内存(包含共享库占用的内存)
PSS - Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)
USS - Unique Set Size 进程独自占用的物理内存(堆内存,独占)
VSS >= RSS >= PSS >= USS
可以使用smem工具查看进程的VSS,RSS.PSS,USS值,USS值就是堆内存占用,内存泄漏一般只看这个。
安装: $ sudo apt-get install smem
内存泄漏的判定,查看USS,多时间点采样,震荡发散的内存消耗就是存在泄漏.
。内存和IO交换
分两类:
a.有文件背景的页(file-backed),比如读写文件,程序代码段属于这类,在硬盘中有实在的文件存在;
b.没有文件背景的页,俗称匿名页,比如栈内存,堆内存等,这类内存的交互通过硬盘上的swap分区来实现匿名页的交换.
文件首次载入内存的page cache中,page cache相当于内存中文件的副本,进程通过操作page cache来实现对文件的读写.
$ free
total used free shared buffers cached
Mem: 16340236 14154128 2186108 482520 1835924 3946088
-/+ buffers/cache: 8372116 7968120
Swap: 31875068 384264 31490804
总物理内存大小 = total +reserved内存(开机预留好,包括kernel的代码段,data,bss....)
total = used + free
buffers :直接从裸分区读取的数据到内存的page cache;
cached:从文件背景读取到内存的page cache;
两个是一个东西,背景不一样。
页交换使用LRU算法,最近最少使用的被交换出去
内核中使用kswapd进程作为内存回收.可以回收两类内存页。
zram原理:从内存中划分一块区域用于匿名页交换替代硬盘中的swap分区,压缩需要交换的匿名页,zram可以提供内存可用空间,但是会消耗CPU性能,需要平衡.
2、进程管理
。数据结构
进程是资源分配的单位,线程是调度的单元,这是经典定义.
内核中每一个进程都有一个数据结构是task_struct,每一个task_struct都包含着mm 资源,file资源,signal资源指针,每个task_struct之间有三种联系的视角:
a: 形成双链表 -- 方便快速遍历所有进程;
b: 形成树 -- 方便父子进程的查询;
c: 形成哈希 -- 方便从pid找进程,比如:kill -9 $pid;
这是典型的以空间换时间的算法,提供不同的视角下的时间最短查询.
。生命周期
六种:ready,run,stop,sleep,disk-sleep(深度睡眠)
sleep(浅度睡眠)可以被中断或者信号唤醒,而深度睡眠只能被资源唤醒,这里资源就是你要等的东西,比如mutex lock,代码段的page fault等。
僵尸进程:子死父没有及时清场的一种临时状态,子进程挂了后,父进程需要调用wait4pid接口才会消失,僵尸进程基本不暂用系统资源了。
。进程和线程的区别
内核中进程和线程都是使用task_struct描述,区别在于内存资源,文件资源,信号资源等是否共享,所以线程也称为轻量级的进程.对于调度器来说,只要是task_struct就可以调度.所以在内核中,进程和线程可以理解为同义词.
。进程0,进程1
开机后第一个进程就是进程0,最后会称为idle进程,idle进程优先级最低,idle进程拿到cpu后会执行WFI指令进入低功耗状态,任何来一个中断就会唤醒调度到新的进程,这样非常有利于电源管理的设计.
进程1就是init进程,用户空间所以的进程都是1号进程直接或者间接fork出来的.
。进程调度
吞吐和响应本是一对矛盾行为,需要根据业务需求来选择侧重.
进程调度类型分为内核RT进程和普通用户进程,进程有分IO消耗型(鼠标)和CPU消耗型(编译).
a: RT进程调度策略又可以分为sched_fifo,sched rr类型,
sched_fifo:同优先级进程拿到cpu后,必须等当前进程运行完退出才交出CPU;
sched_rr: 同优先级进程直接轮转获得CPU时间片.
0-99是RT进程优先级,100-139是普通用户进程优先级,数字越大优先级越高,高优先级进程可以抢占低优先级进程.
b: 普通进程的调度是 CFS-完全公平调度算法,使用红黑色数据结构,基本原理比较简单,总是调度vrruntime最小的进程,vrruntime = physical runtime/(nice权重系数),所以一个普通进程运行的越久,他的优先级越低,一个进程睡的越久,优先级越高,被调度的概率越高,优先级最高的进程就是睡眠越久而且nice值越高的IO消耗型进程.
。SMP负载均衡
a: RT进程:N个优先级最高的RT进程均匀分布到各个核;
b: 普通进程:核心思想是以“劳动为荣”,比如新fork出来一个进程,exec的时候会把它推到最闲的核上去运行
。cgroup - 资源控制.
核心就是分层调度,各个group内CFS
。RT-OS
为什么linux不是一个硬实时的操作系统?
硬实时强调一定时间内必须完成调度,进程总是运行在4类区间:
a: 硬中断 - 外部中断
b: 软中断-系统调用
c: 不可调度的进程上下文,比如陷入内核的spinlock保护区
d: 可调度的进程上下文
只有第4类区间是可以实时抢占调度的,前面三类的时间都无法确定,所以无法满足硬实时OS的要求。
RT-patch的原理:
a: 中断线程话 -- 是线程就可以抢
b: 优先级继承协议 -- 临时提高优先级,不受中等优先级进程的干扰
c: spinlock换成mutex,mutex可以睡眠
打上补丁后,基本上可以达到硬实时OS的需求.
3,内核启动流程,从head.S开始到init进程创建.
a: 切换CPU到svc模式,使能d-cache和i-cache,使能MMU;
b: 跳转到start_kernel函数执行,初始化特定体系结构的设置;
c: 解析uboot传入的命令行参数,是否使能早期串口打印;
d: 初始化各种核心数据结构,比如内存管理,异常处理,中断向量,dts,cgroup,等等;
e: 创建1号init进程和2号kthread进程,开始驱动初始化.
f: 最后是用户空间初始化,0号进程演变为idle进程.
4、内核死机等异常的分析手法,策略
分类型:
a: 调用BUG()出现的异常属于人为主动上报异常,一般可以直接从oops信息中找到问题点;
b: 异常现场和真实原因重合的异常,同上可以根据oops的pc指针位置,相关寄存器信息判断异常类型是未定义指令异常,还是data abort,或者其他类型;
c: 异常现场和真实原因不重合的类型,抓ramdump使用工具离线分析寄存器信息,确认异常的类型,观察异常线程的变量参数是否异常,确认是否内存被踩导致,若是kmalloc导致的内存被踩,可以打开slub debug浮现问题后抓取。
d: 若是死锁类问题,需要抓到所以D状态的进程调用栈,逐一排查找出互锁关系,进一步分析原因.如果有必要,需要打开mutex debug等开关辅助调试.
5、KVM,qemu虚拟化的架构认识,实现原理等认识
kvm - kernel-based virtual machine(基于内核的虚拟机)
基于intel,AMD提供的虚拟化平台,不提供硬件虚拟化操作,IO操作借助QEMU完成.
guest作为一个普通进程运行于宿主机.
guest的CPU(vCPU)作为进程的线程存在,并受到宿主机内核的调度.
KVM整体架构:

kvm提供CPU,内存模拟,qemu提供IO模拟.
kvm提供一个 /dev/kvm字符设备,qemu通过ioctl和内核kvm驱动交互,执行初始化,内存分配,指令集加载等操作.
guest的所以硬件操作都由qemu接管,qemu负责和宿主机真实硬件交互.
KVM简单来说就是由两部分构成:
a: KVM驱动,已经是内核一部分,负责虚拟机创建、内存分配、虚拟寄存器读写,和虚拟cpu运行;
b: qemu模拟虚拟机的用户空间组件,模拟IO操作访问外设的途径.
QEMU是完整的纯软件的虚拟化解决方案,性能比较低,KVM提供CPU和内存的模拟+QEMU提供IO模拟相结合实现互补.
KVM运行模式:
客户模式:guest os运行模式,其本身又包含用户模式和内核模式
用户模式:linux os的用户模式,qemu运行在这个模式
内核模式:linux kernel运行模式,kvm内核驱动模块运行在这个模式
ARM处理器有hypervisor层,虚拟化的硬件支持。
6. 内核锁
a. 类型:信号量锁(现在少用了)
b. mutex lock,可以睡眠,会引起上下文切换,效率不及spinlock
c. spinlock,不允许睡眠,会关抢断,中断中使用spin lock/unlock,进程上下文中使用spinlock irq save/restore. -- 如果当前保护的函数不会被中断上下文打断就不用irqsave,否则就需要用spinlock irqsave,因为中断会打断spinlock,然后又进入等待spinlock的情况,导致dead lock.
d. rcu, read-copy-update,一种支持并发的保护机制,很复杂.
e. 原子锁,atomic,现在用的少了。
使用注意:
被保护的代码如果不允许睡眠,追求效率,那么用spinlock,它不会切换上下文,比如中断上下文不可用mutex lock.




本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux内核相关知识点记录【内存管理】【进程调度】【异常调试】【锁】【kvm虚拟化】【内核启动】 的相关文章

  • 分布式计算,泛在计算,BOINC

    BOINC平台简介 知乎 Download BOINC client software 开源源代码 https github com BOINC boinc 介绍 https www equn com wiki BOINC 使用指南 htt
  • 【Antdv】a-date-picker showTime带时间默认00:00:00

    show time 默认当前系统时间 设置默认 00 00 00
  • 预编码

    原则上说MIMO技术并不一定需要预编码 使用预编码的前提是发射端可以及时获取信道信息 也就是CSIT 在通常情况下 只有接收端可以知道信道信息CSIR 在这个情况下 接收端通过复杂的信号处理算法 如MMSE SIC 可以解调出多路的MIMO
  • Zookeeper 通知更新可靠吗? 解读源码找答案!

    欢迎大家前往腾讯云 社区 获取更多腾讯海量技术实践干货哦 本文由特鲁门发表于云 社区专栏 导读 遇到Keepper通知更新无法收到的问题 思考节点变更通知的可靠性 通过阅读源码解析了解到zk Watch的注册以及触发的机制 本地调试运行模拟
  • 软件架构及几种典型框架

    什么是软件架构 什么是软件框架 很多时候 我们常常会混用架构和框架这两个词 实际上 广义上的架构和框架在概念上有很大的不同 架构给人的感觉 包容上更大 所以实际上架构是包含了框架的概念的 广义的架构应为一个系统的架构 不仅仅涉及软件中的技巧
  • BOM编程

    1 BOM概述 BOM 浏览器对象模型 Browser Object Model 它提供了独立于内容的 可以与浏览器窗口进行互动的对象结构 通过BOM可以操作浏览器窗口 比如弹出框 控制浏览器跳转 获取分辨率等 BOM是把 浏览器 当做一个
  • 实操理解node_modules目录结构

    环境 2022 8 16 node v gt v16 15 1 npm v gt 8 11 0 yarn v gt 1 22 19 pnpm v gt 7 9 0 npm0 mkdir npm0 cd npm0 npm install el
  • 从源头理解Batch Normalization (顺带搞懂为什么做参数初始化)

    一 BN LN等一系列Normalization方法的动机 因为一个网络中某层的参数的梯度 最终是由训练样本中这层输入的各个feature的具体数值决定的 如果feature的数值变化范围过大 比如不同特征的含义就导致了取值范围不在一个数量
  • 标签传递算法:java版

    标签传递算法 java版 标签传递算法 java版 java labelpropagation 本地测试 数据集 LPAlgorithm loadJSON vertexAdjMap和vertexInAdjMap的区别在哪里 根据每个节点的权
  • 【计算机视觉

    文章目录 一 前言 二 简介 三 相关方法 3 1 实时目标检测器 3 2 端到端目标检测器 3 3 目标检测的多尺度特征 四 检测器端到端速度 4 1 分析NMS 4 2 端到端速度基准 五 The Real time DETR 5 1
  • 我的世界虚拟服务器联机,我的世界模拟城市联机教程-的世界怎么联机

    我的世界联机分为服务器联机和本地WIFI联机两种 首先我们先说下服务器联机方法 一 打开游戏后 点击Play进入游戏列表 再点击右上角的Edit 然后点击External 然后将会进入添加服务器的界面 第一行 ServerName 那里填写
  • 安卓默认启动的活动界面

    是在AndroidManifest 的activity 的标签中 加入 的活动是默认启动的
  • ENVI5.3安装

    一 下载地址 BT下载地址 链接 https pan baidu com s 1Z1l0qXQjSaEf3VQj9 qcAw 提取码 4il4 压缩包下载 链接 https pan baidu com s 1EbdO0uDiBdbFFdQx
  • java中定义score方法_elasticsearch 自定义 script score JavaAPI查询详解

    一 自定义score的应用场景 先打个比方 比如新产品上架了 我想让最新上架的产品搜索时候 排在前面 怎么办呢 很简单按时间排序 嗯这种方法很好实现 但下面又有个需求 比如我要求排序中上架时间的比重为40 自营产品为20 促销产品的比重为4
  • git branch管理常用命令

    本文转载至 http www 2cto com os 201307 229235 html git branch管理常用命令 查看本地分支 plain git branch dev master 代表当前位于dev分支 查看远程分支 pla

随机推荐

  • python netcdf4读取nc格式的气象数据

    一 nc格式数据介绍 NetCDF全称为network Common Data Format 中文译法为 网络通用数据格式 netcdf文件开始的目的是用于存储气象科学中的数据 现在已经成为许多数据采集软件的生成文件的格式 从数学上来说 n
  • PROJ4是什么?

    GIS Geographic Information System 地理信息系统 领域中最常提及 的一个概念是坐标系统 当我们提及一个地理位置的时候 与之伴随而产生的是该位置必定在一个空间参考下 当我们使用GPS设备获取到某个位置的经纬度的
  • Linux常用配置及硬件检测命令

    一些比较常见的linux命令 主要用于检测服务器的配置和硬件信息 包括 操作系统 CPU 内存 硬盘分区 系统时间 负载 网络相关 进程 用户 开关机 启动等方面 适用于主流操作系统 常见的centos ubuntu debian等 操作系
  • python selenium 三种等待方式详解

    引言 当你觉得你的定位没有问题 但是却直接报了元素不可见 那你就可以考虑是不是因为程序运行太快或者页面加载太慢造成了元素还没出来就已经报错了 试着程序调试程序运行速度 等待元素可见再继续运行程序 1 强制等待 sleep 优点 简单明了 需
  • 【国家参考文献标准GB/T 7714—2015】

    GB T 7714 2015 2 1 参考文献著录方法几种主要类型的参考文献 专著 专著中的析出文献 连续出版物 连续出版物中的析出文献 专利文献 电子文献等 的著录项目与格式要求如下 2 1 1 专著 图书 M 指以单行本或多卷册形式 在
  • 游戏开发unity编辑器扩展知识系列:获取选中文件的路径

    参考 Unity 编辑器下获取选择文件路径
  • Python中如何输出换行?

    Python中如何输出换行 在Python中 输出换行可以使用的方法有两种 分别是用转义符号或使用print 接下来我们通过这篇文章为大家详细的讲解一下 方法1 用转义符号 str3 老男孩教育 n str4 帮助有志向的年轻人通过努力学习
  • Threejs + vue 学习- VR 看房

    知识点 参考链接 threejs github 图片下载 https gitee com congyingcy threejs learning tree master three public imgs 直接跳转 代码下载 直接跳转 立方
  • maven自定义Archetype

    1 创建模板项目 如下 2 模板项目的pom xml中添加archetype插件
  • 光纤验收测试标准、参数及常用设备

    在光纤工程项目中必须执行一系列的测试以确保其完整性 一根光缆从出厂到工程安装完毕 需要进行机械测试 几何测试 光测及传输测试 前3个测试一般在工厂进行 传输测试则是光缆布线系统工程验收的必要步骤 综合布线工程电气测试包括电缆系统电气性能测试
  • ChatGPT追祖寻宗:GPT-1论文要点解读

    论文地址 Improving Language Understanding by Generative Pre Training 最近一直忙着打比赛 好久没更文了 这两天突然想再回顾一下GPT 1和GPT 2的论文 于是花时间又整理了一下
  • mysql(十)mysql主从复制--主库切换

    概述 可能为了更迭升级服务器 或者主库出现问题 又或者只是希望重新分配容量 此时需要切换主库 如果这是计划内的切换 会相对容易点 只需要在从库上使用CHANGE MASTER TO命令 并设置合适的值 大多数的值都是可选的 至少要指定需要改
  • C++数据结构笔记(8)循环链表实现

    1 循环链表与单链表的区别在于尾部结点存在指向头结点的指针 2 无论尾部结点指向第一个结点 头结点 还是第二个结点 第一个有效结点 都可以被称为循环链表 3 判断循环结束的两种方式 遍历次数等于size 或判断next指针是否指向头结点 4
  • Ubuntu 20.04 LTS 系统下 安装Nvidia 显卡驱动、CUDA、cuDNN, 并可进行CUDA版本切换

    因为做深度学习的研究项目 为全新机器在Ubuntu 20 04 LTS 系统下 安装Nvidia 显卡驱动 Cuda Cudnn 并进行CUDA版本切换 成功安装完成了 写个记录 1 安装Nvidia 显卡驱动 步骤一 安装更新软件列表和依
  • 模糊测试--强制性安全漏洞发掘

    文档分享地址链接 链接 http pan baidu com s 1dDeROHj 密码 o15z 前 言 我知道 人类和鱼类能够和平共处 George W Bush 2000年9月29日 简介 模糊测试的概念至少已经流传了20年 但是直到
  • python游戏毕设项目 愤怒的小鸟游戏设计与实现 (源码)

    文章目录 0 项目简介 1 游戏介绍 2 实现效果 3 开发工具 3 1 环境配置 3 2 Pygame介绍 4 具体实现 5 最后 0 项目简介 Hi 各位同学好呀 这里是L学长 今天向大家分享一个今年 2022 最新完成的毕业设计项目作
  • Linux地图投影Proj4应用,proj4 地图投影坐标转换库 - 下载 - 搜珍网

    压缩包 proj 4 7 0 zip 列表 proj 4 7 0 proj 4 7 0 README proj 4 7 0 configure in proj 4 7 0 aclocal m4 proj 4 7 0 Makefile am
  • RestTemplate使用方法

    单独使用调用其他服务请求 public static void getRestTemplate String urls RestTemplate restTemplate new RestTemplate MultiValueMap
  • S7协议解析

    S7 1 西门子通信场景 西门子设备使用多种不同现场总线协议 例如 MPI Profibus IE Profinet 等 Profinet用于将PLC连接到IO模块 而不是设备的管理协议 S7以太网通信协议 主要用于将PLC连接到 i pc
  • Linux内核相关知识点记录【内存管理】【进程调度】【异常调试】【锁】【kvm虚拟化】【内核启动】

    1 内存管理 怎么阐述自己的理解 硬件原理 分页机制原理 内核内存管理由MMU提供硬件支持 MMU实现虚实地址VA gt PA的转换以及权限检查 虚拟地址和物理地址之间的映射关系是页表机制 每一个页表项都保持物理地址页及其访问权限 页表机制