linux内核之内存管理.doc,linux内核之内存管理.doc

linux内核之内存管理

Linux内核之内存管理

作者:harvey wang

邮箱:harvey.perfect@

新浪博客地址:/harveyperfect ,有关于减肥和学习英语相关的博文,欢迎交流

把linux内存管理分为下面四个层面

(一)硬件辅助的虚实地址转换

(二)内核管理的内存相关

(三)单个进程的内存管理

(四)malloc软件

处理器硬件辅助的虚实地址转换(以x86为例)

在x86中虚实地址转换分为段式转换和页转换。段转换过程是由逻辑地址(或称为虚拟地址)转换为线性地址;页转换过程则是将线性地址转换为物理地址。段转换示意图如下

X86支持两种段,gdt和ldt(全局描述段表和局部描述符段表),在linux中只使用了4个全局描述符表,内核空间和用户空间分别两个gdt,分别对应各自的代码段和数据段。也可以认为在linux中变相地disable了x86的段式转换功能。

页转换示意图如下

在linux中x86 的cr3寄存器(页表基地址寄存器)保存在进程的上下文中,在进程切换时会保存或回复该寄存器的内容,这样每个进程都有自己的转换页表,从而保证了每个进程有自己的虚拟空间。

内核管理的内存相关

从几个概念展开内存管理:node、zone、buddy、slab

1、Node

SGI Altix3000系统的两个结点

如上图,NUMA系统的结点通常是由一组CPU(如,SGI Altix 3000是2个Itanium2 CPU)和本地内存组成。由于每个结点都有自己的本地内存,因此全系统的内存在物理上是分布的,每个结点访问本地内存和访问其它结点的远地内存的延迟是不同的,为了优化对NUMA 系统的支持,引进了Node 来将NUMA 物理内存进行划分为不同的Node。而操作系统也必须能感知硬件的拓扑结构,优化系统的访存。

但是Intel x86 系统不是NUMA 系统。为了保持代码的一致性,在x86 平台上,Linux 将所有物理内存都划分到同一个Node。事实上,对于非NUMA 体系结构,也是如此处理的。

Linux系统用定义了数组pg_data_t node_data[MAX_NUMNODES] 来管理各个node。

2、Zone

Linux中Node、Zone和页的关系

每个结点的内存被分为多个块,称为zones,它表示内存中一段区域。一个zone用struct zone结构描述,zone的类型主要有ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM。ZONE_DMA位于低端的内存空间,用于某些旧的ISA设备。ZONE_NORMAL的内存直接映射到Linux内核线性地址空间的高端部分,ZONE_HIGHMEM位于物理地址高于896MB的区域。例如,在X86中,zone的物理地址如下:

内核空间只有1GB线性地址,如果使用大于1GB的物理内存就没法直接映射到内核线性空间了。当系统中的内存大于896MB时,把内核线性空间分为两部分,内核中低于896MB线性地址空间直接映射到低896MB的物理地址空间;高于896MB的128MB内核线性空间用于动态映射ZONE_HIGHMEM内存区域(即物理地址高于896MB的物理空间)。

3、Buddy

如上图所示,每个zone区域都采用伙伴系统(buddy system)来管理空闲内存页面。把所有的空闲页框分组为11个块链表,每个块链表分别包含大小为1,2,4,8,16,32,64,128,256,512和1024个连续的页框。链表编号分别为0,1,2,3,… k… 10。

从buddy system中申请页面过程:

根据申请存储区域大小查找对应的编号为K的块链表。

如果编号K的链表为空,则向编号为k+1的链表申请一个存储区域。如果编号为k+1链表不为空,系统从编号为k+1的链表上拆下一个区域,并将拆下的区域分为两个2^k的区域,一个返还给申请者,另一个则挂到编号为k的链表。

如果编号为k+1的链表也为空,编号为k+2的链表不为空。则从k+2的链表中拆下一个区域变为两个2^(k+1)区域,一个挂到编号为k+1的链表上,把另一个拆为两个2^k的区域,一个返还给申请者,把另一个挂到编号为k的链表上。

如果k+2的链表也为空,则一直向上迭代,直到编号为10的链表为止,如果编号为10的链表还为空,则申请失败。

向buddy system中释放页面过程:

在向buddy system 释放页面时,总会检测释放的页面和链表中其他页面是否可以组成一个更大一级的页面,如果可以组成,则把这两个区域组成一个并挂到更高一级的链表中。这个过程是迭代的,释放过程会一层层向上找伙伴,然后合并成更大的,再向上找伙伴,实在找不到了就停止了!

疑问:按照上面的

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

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

相关文章

SpringBoot项目去除druid监控的底部广告

文章目录一、阿里Druid广告的介绍二、引入Druid的Starter依赖三、编写配置类,进行广告的去除四 、启动项目进行测试五、原理说明一、阿里Druid广告的介绍 如果使用的是阿里Druid的数据库连接池,那么会自带一个数据库的监控页面. 但是其页面底部会有阿里的广告,如下图所示,并且…

精简linux操作系统,Tiny Core Linux—仅10多MB的精简Linux 操作系统发行版

Tiny Core Linux是一款很简约的桌面Linux,体积小且可高度可扩展,基于Linux 3.x内核、Busybox、Tiny X、FLTK图形用户界面、JWM窗口管理器。像其他操作系统最少也要几百MB了,Tiny Core Linux不仅体积小,对硬件配置要求也很高&#…

面试官问你MyBatis中有哪些设计模式,把这篇文章发给他

戳蓝字“CSDN云计算”关注我们哦!作者 | 疯狂的蚂蚁来源 | https://dwz.cn/KFgol1De之前总结过一篇Spring中用到了哪些设计模式:《面试官:“谈谈Spring中都用到了那些设计模式?”》,昨晚看到了一篇很不错的一篇介绍MyBatis中都用到了那些设计…

Linux 启动mysql提示表不存在

编辑my.cnf 设置大小写敏感配置在 vim /etc/my.cnf #添加lower_case_table_names1,忽略大小写 #重启MYSQL服务 service mysql restart,

linux 定时器 代码,linux C++ 定时器代码

linux C 定时器代码:#include #include #include using namespace std;/*union sigval{int sival_int; //integer valuevoid *sival_ptr; //pointer value};struct sigevent{int sigev_notify; //notification typeint sigev_signo; //signal numberunion sigval …

MySQL启动出现The server quit without updating PID file错误解决办法

解决办法其实很简单: 将 /etc/mysql 下的 my.cnf 文件删除,再次启动MySQL服务 删除前注意备份

腾讯云首次公开边缘计算网络开源平台,拥抱5G与万物互联

6月25日,由Cloud Native Computing Foundation (CNCF) 主办的云原生技术大会在上海举办,腾讯云对外展示自身在边缘计算领域的最新进展,首次公开腾讯智能边缘计算网络平台TSEC(Tencent Smart Edge Connector)&#xff0…

linux输入qsub显示错误,linux – 使用qsub运行shellscript的’意外的文件结束’和’错误导入功能定义’错误...

我有以下shellscript:#!/bin/shcd /sw/local/bin/export LD_LIBRARY_PATH/sw/local/lib:/usr/local/Trolltech/Qt-4.7.2/lib:$LD_LIBRARY_PATH./FeatureFinderRaw -in /homes/JG-C1-18.mzML -out /homes/test_remove_after_use.featureXML -threads 20当我从自己的命…

解决SecureCRT与SecureFX中文乱码问题

文章目录一、SecureCRT中文乱码问题解决方法:二、SecureFX中文乱码问题解决方法:2.1. 找到SecureFX配置文件夹2.2. 在配置文件夹下的Sessions子目录中,找到SecureCRT连接对应的Session文件(.ini扩展名),双击…

OpenStack精华问答 | OpenStack服务介绍

关于OpenStack的争议,从未停止,每每关于它的消息,都会一石激起千层浪。今天就让我们看看关于OpenStack的问答吧。1Q : OpenStack服务介绍A : MySQL为各个服务器提供数据存储RabbitMq:为各个服务之间提供通信认证和服务注册Keystone:为各个服务…

实战04_redis-cluster集群搭建

接上一篇:实战_03_Redis基础命令https://blog.csdn.net/weixin_40816738/article/details/99213524 #安装gcc yum install gcc-c #使用yum命令安装 ruby (我们需要使用ruby脚本来实现集群搭建) yum install ruby yum install rubygems #将redis源码包上…

linux网站渗透工具包,ubuntu下安装 kali linux 渗透工具包

相信用过linux系统的盆友都听说过kali linux 它是一个非常好的用于渗透测试的Linux发行版。但是如何在ubuntu下使用kali linux 的渗透工具嘞!LionSec开发出了一个python工具,叫做Katoolin,它可以让你在其他Linux发行版上使用Kali的全部工具。…

OCP China Day“登陆”,最新技术、方案吸睛!

戳蓝字“CSDN云计算”关注我们哦!作者 | 刘晶晶众所周知,OCP在2011年由Facebook发起成立,核心会员超过200家,其中更是包括Google、微软、Intel、IBM等企业,超过7000家企业参与了该社区的活动;2018年OCP非董…

实战_05_SpringBoot整合redis单机版本

接上一篇:实战04_redis-cluster集群搭建https://blog.csdn.net/weixin_40816738/article/details/100635263 下一篇:实战_06_SpringBoot整合edis-cluster集群版本https://blog.csdn.net/weixin_40816738/article/details/100658669

linux下字体怎么安装方法,linux安装字体方法

1.查看系统中文字体#fc-list :langzh2.如果提示commont not fount 说明为安装fontconfig3.安装fontconfig#yum -y install fontconfig4.再次查看系统中文字体#fc-list :langzh5.确认是否存在字体 -->> simhei.ttf6.创建目录:#mkdir -p /usr/share/fonts/my_fo…

实战_06_SpringBoot整合redis-cluster集群版本

接上一篇:实战_05_SpringBoot整合redis单机版本https://blog.csdn.net/weixin_40816738/article/details/100658608

linux中ssh启动报错,Linux(Ubuntu18)中启动ssh时的报错

今天配置了一台新的Ubuntu的机器,在修改完ssh的配置文件并准备开启ssh的时候,无论是启动ssh:/etc/init/d/ssh start还是重启ssh服务:/etc/init/d/ssh restart都显示错误:Starting ssh (via systemctl): ssh.serviceJob…

SpringBoot集成Shiro前后端分离使用redis做缓存

文章目录一 、shiro介绍1、基础介绍2、基本功能点3、基本流程图二、 常用的权限管理表关系2.1. 表组成2.2. 表结构三、实战案例3.1. 案例介绍3.2. 依赖3.3. Shiro全局配置3.4. 自定义ShiroRealm3.5. ShiroUtils3.6. 自定义SessionManager3.7. 登录/出主方法3.8. 测试主方法四、…

边缘计算容器化是否有必要?

戳蓝字“CSDN云计算”关注我们哦!作者 | Steve来源 | 边缘计算中文社区简要由于容器有轻量级、安全性、秒级启动等优秀的特性,容器天然的轻量化和可移植性,非常适合边缘计算的场景,这一点边缘计算的厂家和开发者们都心知肚明。而且…

ipcp协议 Linux,Linux命令Man解释:PPPD(8) :点对点daemon协议

名称pppd - 点对点协定隐形程式(Point to Point Protocol daemon)语法pppd [ 选项 ] [ 终端设备名称(tty_name) ] [ 速率 ]描述这个点对点协定 (PPP) 提供一种在点对点串列线路上传输资料流(datagrams) 的方法。PPP 是由三个部份所组成的:一个在串列线路上封装(enca…