连续内存分配

  物理地址空间:加载到寄存器中的地址,内存单元真正的地址,其位数由地址总线数决定,32位则表示32条地址总线,编号从0一直到可用内存的最大值。

  逻辑地址空间:CPU运行时程序可看到的地址,由内部和编程时使用,比如C语言中读取一个指针变量本身的值,读到的就是逻辑地址,它是相对于当前数据段的地址也就是偏移地址。(段基地址+偏移地址构成线性地址,线性地址通过MMU根据分页机制转化成物理地址)

逻辑地址的生成:

  1.编译时获取。在已知最后地址的情况下编译时直接写死地址。如果起始地址改变需要重新编译。

  2.加载时。起始地址未知下,编译时生成可重定位的代码,加载时生成绝对地址。

  3.执行时。执行到该指令时知道确切访问地址。在程序运行时可以移动内存中的地址,更灵活。

连续内存分配:给进程分配不小于指定大小的,物理地址连续的内存区域

动态内存分配:程序被加载执行时,分配一个进程大小可改变的分区

         需要维护数据结果:所有已分配分区 空闲分区

分配策略:最先分配(first-fit) 最佳分配(best-fit)最差匹配(worst-fit)

  1.最先匹配:按照地址顺序最先找到的比要求空间大的分区,可在高地址留下比较大块的分区,但容易留下外碎片,并且分配大块时速度较慢。

  2.最佳匹配:找到一个比要求大但又大的最少的分区。空闲分区列表按照大小排序,释放时和地址临近的空闲分区合并。分配尺寸较小时效果好,避免大块分区被拆分,减少外碎片的大小,但容易产生无用小碎片。

  3.最差匹配:空闲分区由大到小排,找满足要求的最大的分配。释放时与临近的空闲分区合并。中等大小分配时效果最好,避免出现太多小碎片。但释放分区慢,容易破坏大分区。

内存碎片:空闲内存不能被利用

  1.内部碎片:分配单元之间不能被使用的内存。由于内存过小,申请单元都大于该内存块,无法使用。

  2.外部碎片:分配单元内部无法使用。由于分配时取整,申请510字节实际分配了512字节,2字节无法被利用

碎片整理:

  通过调整进程占用分区位置来减少或避免分区碎片

时间: 2024-10-13 04:19:28

连续内存分配的相关文章

非连续内存分配

非连续分配允许一个程序分散地装入到不相邻的内存分区中,根据分区的大小是否固定分为分页存储管理方式和分段存储管理方式. 基本分页存储管理方式 固定分区会产生内部碎片,动态分区会产生外部碎片,这两种技术对内存的利用率都比较低.我们希望内存的使用能尽量避免碎片的产生,这就引入了分页的思想:把主存空间划分为大小相等且固定的块,块相对较小,作为主存的基本单位.每个进程也以块为单位进行划分,进程在执行时,以块为单位逐个申请主存中的块空间. 分页的方法从形式上看,像分区相等的固定分区技术,分页管理不会产生外部

linux内核内存分配(三、虚拟内存管理)

在分析虚拟内存管理前要先看下linux内核内存的详细分配我开始就是困在这个地方,对内核内存的分类不是很清晰.我摘录其中的一段: 内核内存地址 =========================================================================================================== 在linux的内存管理中,用户使用0-3GB的地址空间,而内核只是用了3GB-4GB区间的地址空间,共1GB:非连 续空间的物理映射就位于3G

内存分配与内存管理的一些理解

内存分配方式与内存分配算法 内存分配方式有两种,连续内存分配方式和离散内存分配方式.不同的分配方式又有不同的分配算法. 内存分配算法,其实就是:有一大块空闲的资源,如何合理地分配资源?内存分配的思想可以用到很多其他的领域. ①连续内存分配方式 1)固定分区分配 将内存划分成若干个固定大小的块.将程序装入块中即可.内存划分成各个块之后,块大小不再改变.当然,划分块的方式有:所有的块大小相等:划分的块大小不相等. 这种方式,在实际的内存分配之前,就已经知道了所有的内存块大小了. 2)动态分区分配 需

操作系统内存分配

when why what how 为什么 OS 需要中断.系统调用.异常? why? 现实中有不少恶意应用,如果它能随意调用系统的一些指令,那后果不堪设想.那么就需要有个人确保其安全,操作系统可以信任其安全所以如果一些应用需要调用系统的一些指令通过操作系统来检查确保其安全. 中断:是指CPU对系统发生的某个事件做出的一种反应,CPU暂停正在执行的程序,保留现场后自动地转去执行相应的处理程序,处理完该事件后再返回断点继续执行被"打断"的程序. 如果某一个程序运行了足够长用完了分配给它的

动态内存分配连续内存空间的二维数组

可以直接使用一维数组来模拟二维数组,下面的代码就是在此基础上,用一个二级指针指向一维数组的相应地方,详见代码 #include <stdio.h> #include <malloc.h> int main() { int row,col,i,j,n=0; row=col=3; //malloc连续内存的二维数组 int **arr=(int**)malloc(row*sizeof(int*));//分配二维数组 arr[0]=(int*)malloc(row*col*sizeof(

C++ Primer 学习笔记_98_特殊工具与技术 --优化内存分配

特殊工具与技术 --优化内存分配 引言: C++的内存分配是一种类型化操作:new为特定类型分配内存,并在新分配的内存中构造该类型的一个对象.new表达式自动运行合适的构造函数来初始化每个动态分配的类类型对象. new基于每个对象分配内存的事实可能会对某些类强加不可接受的运行时开销,这样的类可能需要使用用户级的类类型对象分配能够更快一些.这样的类使用的通用策略是,预先分配用于创建新对象的内存,需要时在预先分配的内存中构造每个新对象. 另外一些类希望按最小尺寸为自己的数据成员分配需要的内存.例如,

内存分配及堆与栈的区别

1.内存分配方式 内存分配方式有三种: 1.从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量. 2.从堆栈上分配.函数内的局部变量的存储单元,函数执行结束时这些存储单元自动被释放.栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限. 3.从堆上分配,亦称动态内存分配.程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存.动态内存的生存期由程序员决定

垃圾收集器与内存分配策略

①对于java虚拟机来说,垃圾收集器主要关注的内存区域是 堆和方法区. ②垃圾收集器就是要收集那些已经“死了”的对象.如果判断一个对象是否存活? 对象引用计数法 对象引用增加一个,那么相应的计数器加1,否则,减1. 优点:实现简单 缺点:不能处理对象间的循环引用.a引用b,b同时引用a. 可达性分析 如果节点到root节点可达,则证明是存活的:否则,已死.所以对于下图的o5,o6,o7虽然他们是循环引用的,但是到root节点无可达,所以已死可清除. ③垃圾回收器对于不同类型引用的回收规则 强引用

C++动态内存分配

笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D实战核心技术详解>电子工业出版社等. CSDN视频网址:http://edu.csdn.net/lecturer/144 C / C ++中的动态内存分配是指程序员手动执行内存分配, 动态分配的内存分配给堆,非静态和局部变量获取在Stack上分配的内存.详情查看上篇博文:C程序的内存布局. 什么是应用程序? 动态分配的