xv6源码解析(三)——内存管理

news2024/12/24 20:49:55

01 内存管理

内存管理:通过编写物理页分配器,以链表管理所有空闲页帧, 实现了对物理页帧的回收与分配;在xv6系统sbrk内存管理方式的基础上,添加了进程用户空间非连续分区的分配。

image-20221106094833920

image-20221106094745101

内存管理参考链接

mmap

02 sbrk机制

描述:
brk()和sbrk()改变程序间断点的位置。程序间断点就是程序数据段的结尾。(程序间断点是为初始化数据段的起始位置).通过增加程序间断点进程可以更有效的申请内存 。当addr参数合理、系统有足够的内存并且不超过最大值时brk()函数将数据段结尾设置为addr,即间断点设置为addr。sbrk()将程序数据空间增加increment字节。当increment为0时则返回程序间断点的当前位置。

返回值:
brk()成功返回0,失败返回-1并且设置errno值为ENOMEM(注:在mmap中会提到)。
sbrk()成功返回之前的程序间断点地址。如果间断点值增加,那么这个指针(指的是返回的之前的间断点地址)是指向分配的新的内存的首地址。如果出错失败,就返回一个指针并设置errno全局变量的值为ENOMEM。

总结:
这两个函数都用来改变 “program break” (程序间断点)的位置,改变数据段长度(Change data segment size),实现虚拟内存到物理内存的映射。
brk()函数直接修改有效访问范围的末尾地址实现分配与回收。sbrk()参数函数中:当increment为正值时,间断点位置向后移动increment字节。同时返回移动之前的位置,相当于分配内存。当increment为负值时,位置向前移动increment字节,相当与于释放内存,其返回值没有实际意义。当increment为0时,不移动位置只返回当前位置。参数increment的符号决定了是分配还是回收内存。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nUPoIDFQ-1668171558979)(https://image-1312312327.cos.ap-shanghai.myqcloud.com/20170116174212008)]

03 myalloc/myfree机制

xv6内存管理方法:sbrk机制

在学习完xv6的进程分配和释放内存的方式后,发现xv6只允许扩展和收缩进程空间,也就是采用了linux中提供的sbrk机制。

  • sys_sbrk()将进一步调用growproc(n)进行内存空间的调整 , proc.c中的growproc(n)底层实现原理就是根据传入参数n的正负进行扩展和收缩内存
  • kalloc()会分配一个物理页帧,kfree()会释放一个物理页帧,mappages()用于建立虚存地址和物理页帧之间的关系
  • 如何实现Linux的alloc()和free()

myalloc实现

进行myalloc分配内存的时候

(1)需要查找合适的地址范围,并创建vma进行描述

在sbrk调用的基础上,找到size,然后myalloc传入的参数n就是要分配内存空间的大小,继续往上的vm空间查找合适的地址范围

(2)要用kalloc分配足够的物理页帧,并用mappages()将这些页帧映射到指定的虚存地址上

找到对应的地址范围后,分配物理页帧,同时进行页表映射,把物理页帧映射到虚存地址上去

int 
mygrowproc(int n){                 // 实现首次最佳适应算法
	struct vma *vm = proc->vm;     // 遍历寻找合适的空间
	int start = proc->sz;          // 寻找合适的分配起点
	int index;
	int prev = 0;
	int i;

	for(index = vm[0].next; index != 0; index = vm[index].next){
		if(start + n < vm[index].address)
			break;
		start = vm[index].address + vm[index].length;
		prev = index;
	}
	
	for(i = 1; i < 10; i++) {            // 寻找一块没有用的 vma 记录新的内存块
		if(vm[i].next == -1){
			vm[i].next = index;			
			vm[i].address = start;
			vm[i].length = n;

			vm[prev].next = i;
			
			myallocuvm(proc->pgdir, start, start + n);
			switchuvm(proc);
			return start;   // 返回分配的地址
		}
	}
	switchuvm(proc);
	return 0;
}

int 
myallocuvm(pde_t *pgdir, uint start, uint end) {
	char* mem;
	uint a;

	a = PGROUNDUP(start);
	for(; a < end; a += PGSIZE) {
		mem = kalloc();
		memset(mem, 0, PGSIZE);
    mappages(pgdir, (char*)a, PGSIZE, V2P(mem), PTE_W|PTE_U);
	}
	return (end-start);
}

myfree实现

进行myfree释放内存的时候

(1)需要释放所涉及的页帧,逐个解除页表映射

(2)删除vma

int
myreduceproc(int address){  // 释放 address 开头的内存块
	int prev = 0;
	int index;
	for(index = proc->vm[0].next; index != 0; index = proc->vm[index].next) {
		if(proc->vm[index].address == address && proc->vm[index].length > 0) {
			mydeallocuvm(proc->pgdir, proc->vm[index].address, proc->vm[index].address + proc->vm[index].length);			
			proc->vm[prev].next = proc->vm[index].next;
			proc->vm[index].next = -1;
			proc->vm[index].length = 0;
			break;
		}
		prev = index;
	}
	switchuvm(proc);
	return 0;
}

int
mydeallocuvm(pde_t *pgdir, uint start, uint end) {
	pte_t *pte;
	uint a, pa;

	a = PGROUNDUP(start);
	for(; a < end; a += PGSIZE) {
		pte = walkpgdir(pgdir, (char*)a, 0);
		if(!pte)
			a += (NPTENTRIES - 1) * PGSIZE;
		else if((*pte & PTE_P) != 0){
			pa = PTE_ADDR(*pte);
			if(pa == 0)
				panic("kfree");
			char *v = P2V(pa);
			kfree(v);
			*pte = 0;
		}
	}
	return 1;
}

myalloc测试代码

myalloc => myalloc、myfree => mygrowproc、myreduceproc => myallocuvm、mydeallocuvm

#include "types.h"
#include "stat.h"
#include "user.h"


int
main(int argc, char *argv[]) {
  // int pid = getpid();   
  // map(pid);
  
  char* m1 = (char*)myalloc(2 * 4096);
  char* m2 = (char*)myalloc(3 * 4096);
  char* m3 = (char*)myalloc(1 * 4096);
  char* m4 = (char*)myalloc(7 * 4096);
  char* m5 = (char*)myalloc(9 * 4096);

  m1[0] = 'h';
  m1[1] = '\0';


  printf(1,"m1:%s\n",m1);
  myfree(m2);

  //m2[1] = 'p';

  myfree(m4);
  
  // map(pid);
  sleep(5000);
  myfree(m1);
  myfree(m3);
  myfree(m5);
  // char *p=(char *)0x0000;
  // for(int i=0x0000;i<0x08;i++)
  //     *(p+i)='*';

  // printf(1,"This string shouldn't be modified!\n");
  // exit();


  exit();
}

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

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

相关文章

猿创征文|【Linux】Linux中的gdb调试器的使用

目录 一、什么是gdb&#xff1f; 二、gdb的安装 三、gdb的使用 1、只有debug版可以被调试 2、gdb的常用指令 2.1显示代码&#xff1a;l指令&#xff08;list指令&#xff09; 2.2设置断点&#xff1a;b指令&#xff08;break指令&#xff09; 2.3显示断点/禁用断点/开启…

Linux操作系统~进程fork到wait到底怎么用?

目录 1.fork() &#xff08;1&#xff09;.概念 &#xff08;2&#xff09;.fork的写时拷贝 &#xff08;3&#xff09;.fork常规用法 2.进程终止 &#xff08;1&#xff09;.进程退出场景/退出码 &#xff08;2&#xff09;.进程常见退出方法 1&#xff09;.exit函数 …

类与对象(中级)

目录 1. 包 1.1 包的概念 1.2 导入包中的类 1.3 自定义包 1.4 常见的包 2. Java三大特性 -- 封装 3. Java三大特性 -- 继承 3.1 继承的概念&#xff1a; 3.2 继承的语法 3.3 父类成员访问 3.3.1 子类中访问父类的成员变量 3.3.2 子类中访问父类的成员方法 4. supe…

数据挖掘(六) 层次聚类

数据挖掘&#xff08;六&#xff09; 层次聚类 1.层次聚类简介 层次聚类算法(Hierarchical Clustering)将数据集划分为一层一层的clusters&#xff0c;后面一层生成的clusters基于前面一层的结果。层次聚类算法一般分为两类&#xff1a; Divisive 层次聚类&#xff1a;又称自…

【nacos】5.1 spring cloud + Nacos 实现统一配置管理

1. 解决的问题&#xff1a; 配置动态更新配置集中式管理配置内容的安全性和权限不同部署环境下的配置 2. 环境&#xff1a; ideaspring cloudspring-cloud-alibaba nacosmavenmqtt &#xff08;客户端&#xff0c;服务器采用的是EMQ X 5.0 &#xff09; 3. pom依赖 3.1 父级…

皮卡丘python turtle海龟绘图(电力球版)附源代码

皮卡丘python turtle海龟绘图&#xff08;电力球版&#xff09;附源代码 本文目录&#xff1a; 一、皮卡丘python turtle海龟成品效果图 二、皮卡丘背景介绍 三、皮卡丘卡角色形象 四、愿你拥有一只皮卡丘 五、Python 海龟画图主要方法 &#xff08;1&#xff09;海龟画图…

Allegro在PCB上制作二维码和条形码操作指导

Allegro在PCB上制作二维码和条形码操作指导 当我们需要在PCB放置一个二维码或者条形码的时候,可以不需要额外去贴标签,可以直接在PCB上制作,如下图 制作出来的二维码和条形码是可以直接用扫码程序扫描的 具体操作步骤如下 首先要用was performance allegro productivity…

python Clickhouse 分布式表介绍和创建、插入和查询数据,以及解决遇到的问题

目录 一、分布式表和本地表 原理解析&#xff1a; 二、Clickhouse创建分布式表结构 三、python代码实现&#xff08;亲测有效&#xff09; 四、解决遇到的问题 解决 DB::Exception: Missing columns: wefgrgrfew while processing query: wefgrgrfew, required columns: …

【深度学习】第三章:卷积神经网络

文章目录1. 为什么要使用卷积神经网络&#xff1f;2. 卷积2.1 数学上的卷积2.2 深度学习的卷积3. 卷积的构成4. 卷积的特征5. 卷积的计算(1) 一维卷积计算(2) 二维卷积计算(黑白图片)(2) 三维卷积计算(彩色图片)6. 卷积的优势7. 卷积神经网络7.1 卷积层7.2 池化层7.3 全连接层8…

浅聊一下Nginx

目录 Nginx的下载与安装 去Nginx官网安装&#xff1a;nginx news 直接进入下载页面进行安装 直接安装&#xff1a; 在服务器上使用命令对nginx的安装过程 Nginx命令 Nginx配置文件结构 Nginx配置文件&#xff08;conf/nginx.conf&#xff09;正题分为三个部分&#xff1…

Vue框架的学习(Vue操作指令学习三 V-bind )第三课

Vue框架的学习(Vue操作指令学习三 V-bind )第三课 语法的学习关键在于实操 案例一 V-bind基本操作 通过这个案例了解基本的操作 <div id"app"><img src"./img/1-1 (1).jpg" alt""><!--! 绑定图片利用V-bind指令 --><img v-…

一本通1073;救援(c++)

#include <iostream> #include <cmath> using namespace std; int main() {// 屋顶数目、人数int n, m;// x坐标、y坐标、实际距离、所需时间double x, y, s, sum 0;cin >> n; // 输入屋顶数目for (int i 1; i < n; i){// 输入x、y坐标和人数cin >&g…

Rockland丨艾美捷Rockland大鼠γ-球蛋白说明书

艾美捷Rockland大鼠γ-球蛋白&#xff1a; 大鼠γ-球蛋白组分由含有全抗体和其他非白蛋白血浆蛋白的血清组分组成。丙种球蛋白可用于治疗&#xff0c;以暂时提高患者的免疫力&#xff08;如免疫抑制感染后&#xff09;或增加接受肾移植的可能性。γ-球蛋白级分可作为对照试剂用…

【问题记录与解决】jupyter notebook 无法重命名,无法运行测试代码 || jupyter notebook 中常用的两个快捷键。

可以回顾下之前遇到的小问题&#xff0c;因为这次的问题解决就有赖于之前记录的内容喔&#xff01; 一、问题记录与解决】启动Jupyter&#xff0c;运行代码时报错【Error】 || 通过 Jupyter 建立的Python文件在哪儿 || Jupyter 中 移动 Python 文件 到 指定文件夹 二、【记录】…

nosql期末

文章目录第一章 绪论选择判断题简答题1. NoSQL和关系型数据库在设计目标上有何主要区别&#xff1f;2. 简要总结一下NoSQL数据库的技术特点。第二章 NoSQL数据库的基本原理选择判断简答题1. 描述分布式数据管理的特点。2 什么是CAP原理&#xff1f;CAP原理是否适用于单机环境&a…

数据结构之顺序表

目录一、什么是顺序表二、顺序表的分类1、静态顺序表2、动态顺序表(重要)三、C语言实现顺序表1、顺序表的基本结构&#xff08;2&#xff09;、动态顺序表2、动态顺序表中常见的函数接口&#xff08;1&#xff09;、初始化&#xff08;2&#xff09;、销毁函数&#xff08;3&am…

Java:什么是Quarkus?

Quarkus是一个全栈Kubernetes原生Java框架&#xff0c;用于Java虚拟机(JVM)和原生编译&#xff0c;专门针对容器优化Java&#xff0c;使其成为无服务器、云和Kubernete环境的有效平台。 Quarkus旨在与流行的Java标准、框架和库(如Eclipse MicroProfile和Spring)以及Apache Kafk…

基于FOC电路低次谐波抑制Simulink仿真

Foc电路如下图 当Sa导通时当Sb导通时当Sa导通时 Dc电压全被C2吃了 Lr电流向→ 当Sb导通时 Dc电压全被C1吃了 Lr电流向← 假设C1C2C&#xff0c;开关频率接近无穷、占空比为50%时 Uc1Uc2Udc/2、Ilr0 当占空比D>50%,Uc2增大&#xff0c;Ilr→增大 当占空比D<50%,Uc1增…

【java基础系列】13- java的面向对象

面向对象 程序是为了模拟现实世界&#xff0c;解决现实问题而使用计算机语言编写的指令集合。 1、面向对象的思想&#xff08;Object Oriented Programming&#xff09; 一切客观存在的事物都是对象&#xff0c;万物皆对象。任何对象&#xff0c;一定具有自己的特征和行为 特…

【计算机网络】HTTPS协议的加密流程

文章目录HTTPS简介关于加密过程中的名词SSL中的加密操作对称加密非对称加密证书HTTPS执行流程总结HTTPS简介 HTTPS协议也是应用层的协议&#xff0c;它是在HTTP协议的基础上引入了加密层&#xff0c;称为SSL&#xff08;旧的叫法&#xff09;或TLS&#xff08;新的叫法&#x…