【操作系统】内存管理

要求:

        1、在该实验中,采用可变分区方式完成对存储空间的管理(即存储空间的分配与回收工作)。

        2、设计用来记录主存使用情况的数据结构:已分区表和空闲分区表。

        3、在设计好的数据结构上设计一个主存分配算法,要求实现的基本功能操作有:寻找空闲分区,空闲分区表的修改,已分区表的修改。

        4、在设计好的数据结构上设计一个主存回收算法。其中,若回收的分区有上邻空闲分区和(或)下邻空闲分区,要求合并为一个空闲分区登记在空闲分区表的一个表项里。

代码实现:

//Main.java

package test;
import java.util.Scanner;
public class Main {public static void main(String[] args) {Scanner s = new Scanner(System.in);System.out.print("请输入内存总大小: ");int totalSize = s.nextInt();RAMManager manager = new RAMManager(totalSize);manager.disPlay();while (true) {System.out.println("\n请选择操作:");System.out.println("分配内存:1");System.out.println("回收内存:2");System.out.println("退出:3");int choice = s.nextInt();if (choice == 3) break;switch (choice) {case 1:System.out.print("请输入进程名: ");String name = s.next();System.out.print("请输入分配的内存大小: ");int size = s.nextInt();if (manager.allocate(name, size)) {System.out.println("分配成功!");} else {System.out.println("分配失败! 没有足够的连续空间.");}manager.disPlay();break;case 2:System.out.print("请输入要回收内存的进程名: ");name = s.next();if (manager.breakSpace(name)) {System.out.println("回收成功!");} else {System.out.println("回收失败! 未找到该进程.");}manager.disPlay();break;default:System.out.println("无效选择!");}}s.close();System.out.println("程序结束!");}
}

//RAM.java

package test;
public class RAM {//分区类int start;      // 起始地址int size;       // 分区大小boolean free;   // 是否空闲String name;    // 进程名public RAM(int start, int size, boolean free, String name) {this.start = start;this.size = size;this.free = free;this.name = name;}
}

//RAMManager.java

package test;
import java.util.ArrayList;
import java.util.Comparator;
public class RAMManager { // 内存管理器类ArrayList<RAM> alreadyTable;  // 已分配分区表ArrayList<RAM> freeTable;       // 空闲分区表int sumSize;                        // 内存总大小public RAMManager(int sumSize) {     // 初始化this.sumSize = sumSize;alreadyTable = new ArrayList<>();freeTable = new ArrayList<>();freeTable.add(new RAM(0, sumSize, true, ""));}public boolean allocate(String name, int size) {     // 首次适应算法分配内存for (int i = 0; i < freeTable.size(); i++) {         // 找合适的空闲分区RAM p = freeTable.get(i);if (p.size >= size) {alreadyTable.add(new RAM(p.start, size, false, name));// 分配空闲分区if (p.size > size) {// 更新空闲分区p.start += size;p.size -= size;} else {freeTable.remove(i);                 // 若分配完移除该空闲分区}alreadyTable.sort(Comparator.comparingInt(part -> part.start));// 按起始地址排序已分配表return true;}}return false; // 分配失败}public boolean breakSpace(String name) {     // 回收内存for (int i = 0; i < alreadyTable.size(); i++) {         // 查找要回收的分区RAM p = alreadyTable.get(i);if (p.name.equals(name)) {alreadyTable.remove(i);                 // 从已分配表中移除RAM freePart = new RAM(p.start, p.size, true, "");// 将已回收的分区加入空闲表freeTable.add(freePart);      mergeFreePartitions();                 // 合并相邻的空闲分区freeTable.sort(Comparator.comparingInt(part -> part.start));// 按起始地址排序空闲表return true;}}return false; // 回收失败(未找到该进程)}private void mergeFreePartitions() {     // 合并相邻的空闲分区freeTable.sort(Comparator.comparingInt(part -> part.start));// 按地址排序for (int i = freeTable.size() - 1; i > 0; i--) {// 从后向前合并RAM prev = freeTable.get(i - 1);RAM curr = freeTable.get(i);if (prev.start + prev.size == curr.start) {  // 检查是否相邻prev.size += curr.size;                  // 合并分区freeTable.remove(i); }}}public void disPlay() {     // 打印各个表状态System.out.println("\n当前内存状态:");System.out.println("\n空闲分区表:");System.out.println("    起始地址     大小");for (RAM p : freeTable) {System.out.printf("%8d\t%d\n", p.start, p.size);}System.out.println("已分配分区表:");System.out.println("    起始地址     大小     进程名");for (RAM p : alreadyTable) {System.out.printf("%8d\t%d\t%s\n", p.start, p.size, p.name);}}
}

核心代码流程图:

内存分配流程图

内存回收流程图

运行结果:

初始化内存空间,将进程p1装入内存中

将p2装入内存中

装入p3时发现内存不足

将进程p2回收后再次装入p3,内存空间充足,成功装入

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

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

相关文章

【算法笔记】5.LeetCode-Hot100-矩阵专项

1. 矩阵置零(t73) 中等难度&#xff0c;题目示例如下&#xff1a; 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用原地算法。示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&…

ORACLE 日常查询

一. 查询索引相关1. 查询索引所在的表空间&#xff0c;单个索引的大小SELECT ui.table_name, us.segment_name AS index_name, us.tablespace_name,ROUND(SUM(us.bytes) / 1024 / 1024 / 1024, 2) AS total_size_GB FROM dba_indexes ui JOIN dba_segments us ON ui.index_name…

【DeepSeek实战】17、MCP地图服务集成全景指南:高德、百度、腾讯三大平台接入实战

引言:为什么MCP是地图服务的下一代革命? 在数字化时代,位置服务已成为电商、出行、物流等行业的核心基础设施。但单一地图服务商的局限性日益凸显:某外卖平台因高德地图API突发故障导致30分钟订单配送延迟,某打车软件因百度地图路线规划偏差引发用户投诉激增,某物流企业…

设计模式之【动态代理】

目录 动态代理中存在的概念 JDK动态代理 代理工厂【ProxyFactory】实现【InvocationHandler】 目标类的接口【TargetInterface】 目标类【Target】实现了接口 测试类【JDKDynamicProxyTest】 CGLIB动态代理 添加Maven依赖 代理工厂【ProxyFactory】实现【MethodInterc…

【Linux驱动-快速回顾】一次性快速回顾TTY体系知识点(新手友好)

我将遵循一条严格的“问题驱动”和“演进”的逻辑线索来构建整个TTY知识体系。每引入一个新概念&#xff0c;都是为了解决前一个阶段出现的问题。这样&#xff0c;你不仅能知道“是什么”&#xff0c;更能深刻理解“为什么是这样设计的”。 第〇阶段&#xff1a;最原始的需求 …

深入浅出:让机器听懂世界的耳朵——梅尔频率倒谱系数(MFCCs)

深入浅出&#xff1a;让机器听懂世界的耳朵——梅尔频率倒谱系数&#xff08;MFCCs&#xff09; 在人工智能的浪潮中&#xff0c;语音识别、声纹支付、音乐推荐等技术早已融入我们的日常生活。你是否曾好奇&#xff0c;计算机是如何理解并区分各种复杂的声音信号的&#xff1f;…

Ubuntu22.04安装/使用Gazebo时踩的一些坑

首先&#xff0c;本人原本打算安装gazebo11的&#xff0c;因为官方好像不支持ubuntu22.04&#xff0c;所以要通过PPA和ROS2 humble来安装&#xff0c;安装过程跟着教程来的&#xff0c;也就是下面这篇 ubuntu22.04安装gazebo11&#xff08;ROS2 Humble&#xff09;-CSDN博客 …

CPT203-Software Engineering: Introduction 介绍

目录 1.专业名词定义 1.1计算机软件的定义 1.2软件系统的定义 1.3软件工程的定义 2.软件的失败与成功 2.1 失败 2.2 成功 3.软件开发 Professional software development 3.1 分类 3.2 专业软件开发 professional software development 3.3专业软件开发产品特性 3.4…

诊断工程师进阶篇 --- 车载诊断怎么与时俱进?

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…

奥特曼论人工智能、OpenAI与创业

来自Y Combinator的YouTube视频&#xff0c;展示了OpenAI首席执行官萨姆奥特曼分享的深刻见解。他讨论了OpenAI从一个看似疯狂的通用人工智能&#xff08;AGI&#xff09;梦想&#xff0c;如何发展成为一个全球性的现象。奥特曼强调了早期决策的关键性、吸引顶尖人才的策略&…

React Ref使用

受控与非受控组件 Ref 1.获取原生dom 类组件中&#xff1a;在componentDidMount方法内使用document.getElementById的方法获取到dom元素 1 目标dom增加ref属性 设置为字符串 <h2 reftitleref></h2>function changeRef(){this.refs.titleref.innerHtml }2 函数组件…

地下管线安全的智能监测先锋:智能标志桩图像监测装置解析​

​在城市与乡村的地下&#xff0c;纵横交错的管线是能源与信息传输的关键通道。但深埋地下的电缆、燃气管道等设施&#xff0c;因难以直观监测&#xff0c;面临施工误挖、自然灾害等风险。传统防护手段力不从心&#xff0c;TLKS-PAZ01 智能标志桩图像监测装置的诞生&#xff0c…

Camera相机人脸识别系列专题分析之十六:人脸特征检测FFD算法之libcvface_api.so数据结构详细注释解析

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; Camera相机人脸识别系列专题分析之十六&#xff1a;人脸特征检测FFD算法之libcvface_api.so数据结构详细注释解析…

【字节跳动】数据挖掘面试题0012:数据分析、数据挖掘、数据建模的区别

文章大纲 数据分析、数据挖掘、数据建模的区别一、核心定义与目标二、技术方法差异三、应用场景对比四、三者的关联与递进关系五、面试应答策略 数据分析、数据挖掘、数据建模的区别 一、核心定义与目标 数据分析&#xff1a; 是对已有的数据进行收集、清洗、整理&#xff0c;并…

预警:病毒 “黑吃黑”,GitHub 开源远控项目暗藏后门

在开源生态蓬勃发展的当下&#xff0c;黑客们也将黑手伸向了代码共享平台。当黑产开发者以为在共享 “行业秘笈” 时&#xff0c;殊不知已经掉入了黑客布置的陷阱 —— 看似方便的后门远程控制源码和游戏作弊外挂源码等 “圈内资源”&#xff0c;实则是植入了恶意代码的投毒诱饵…

Qt中的QProcess类

Qt中的QProcess类 QProcess 是 Qt 框架中用于启动和控制外部进程的类&#xff0c;它属于 QtCore 模块。这个类提供了执行外部程序并与它们交互的功能。 一、主要功能 启动外部程序&#xff1a;可以启动系统上的其他可执行程序进程通信&#xff1a;通过标准输入、输出和错误流…

周任务自动化升级:N8N与多维表格无缝联动全解析

.自动化之言&#xff1a; 在上一篇文章中&#xff0c;我们介绍了如何利用多维表格&#xff08;如飞书多维表格或Notion&#xff09;搭建一个灵活的任务管理系统。现在我们将进一步扩展这个系统&#xff0c;借助 N8N 实现周报的自动汇总与邮件发送&#xff0c;真正实现任务管理…

Go语言的web框架--gin

本章内容&#xff0c;会介绍一下gin的运用&#xff0c;以及gin框架底层的内容&#xff0c;话不多说&#xff0c;开始进入今天的主题吧&#xff01; 一.基本使用 gin框架支持前后端不分离的形式&#xff0c;也就是直接使用模板的形式。 模板是什么&#xff1f; 这里可能有同…

企业为什么需要双因素认证?

从进入互联网时代开始&#xff0c;密码是我们个人日常的重要保护。但是单独的密码保护可能已经不再适应当前的数字化时代。密码已经不再足够安全最近发生的各种安全漏洞让我重新审视网络安全。几行代码可能就导致了全球数以百万的登录凭证被泄露。今天&#xff0c;仅仅周期性地…

Spring Boot + 本地部署大模型实现:优化与性能提升!

在Spring Boot中集成本地部署的大模型&#xff08;如LLaMA、ChatGLM等&#xff09;并进行优化&#xff0c;需要从模型选择、推理加速、资源管理和架构设计等多方面入手。以下是完整的优化方案及实现步骤&#xff1a; 一、核心优化策略 1. 模型量化 目标&#xff1a;减少显存占…