程序在内存中的管理和组织
2015-09-07 10:48
190 查看
最开始把问题罗列下
1)程序在内存中逻辑上为何要分段管理
2)程序在内存中的管理分哪些段,分别有哪些功能
要解决上述两个问题就要了解OS对内存的管理模式
说得简单一些,操作系统将内存在逻辑上划分成固定大小的块(一般是4kb),当然虚拟内存(硬盘)也同样是如此划分,然后统一管理
对于程序就是根据块的大小来划分同样大小的页
我们知道像win或者linux可执行的程序都是存放在硬盘里的,那我们如何通过页来将程序加载到内存中呢
考虑一个问题:物理地址=块号*块长度+块内偏移
而页长度=块长度,块内偏移=页内偏移,最后就只剩下页号与块号对应了,当然是通过映射来决定的,这样问题就得到有效解决了
至于如何对应如何计算,给个链接参考一下:http://wenku.baidu.com/link?url=Mu9gPdoNJzRvF66rxZzLqZ1nmjVvjtF_I1_dYohld7nhEQRPeOnviyfXxogAtD9sIpC6f7HHjchIMoEGA14AnvDOkgEuGBqGZ9aLSQVQ--y
然后,考虑问题,为何要分段,原因总结起来就两点:1)方便S调度,2)内存安全访问
相比于页式管理,段式管理是以有逻辑意义为单位存储程序的,这样对于调度来说逻辑上要方便很多,特别是在动态链接时,会非常方便
从安全方便看,有些段在使用时会不断增长,事先不知道会增长到多大,如果采用连续空间的话会出现代码越界的问题,所以段式管理将段在逻辑上分开管理避免了访问越界的问题
最后说一下段页管理的综合使用,目前健全的OS都采用段叶式内存管理办法,一般是先将程序分段,然后再段内分页存储,然后按照段整体来调度,当然在实际调度中还是通过页表换如内存中的,只是调度是按照段来整体换入内存中的。
分别是BSS段,数据段,代码段,堆和栈
其中BSS段是存放没有初始化的全局变量或者静态变量
数据段是存放初始化了的全局变量和静态变量
代码段是存放指令代码
栈由编译器自动分配释放,存放函数的参数值,局部变量的值等
堆是程序员分配和释放的,是动态内存空间,会随着程序运行变大或者缩小
这里说下我注意到的一个问题,就是在子函数(非main函数)中声明一个静态变量并初始化,那么这个变量的生命周期和作用范围到底是什么呢
生命周期是在被初始化开始到整个程序结束,而作用域是在该函数体类,所以在data区其实还有这样一类变量,虽然属于局部变量但是并不在栈中存储
最后说说字符串常量
在data区中有一类属于文字常量,字符串常量就存在此处,有时候也把这一类作为一类单独列出来
从上面可以得出结论,分段是根据生命周期来分类的,而作用域范围是标注的
1)程序在内存中逻辑上为何要分段管理
2)程序在内存中的管理分哪些段,分别有哪些功能
要解决上述两个问题就要了解OS对内存的管理模式
1.OS中段页式管理
首先说说页式管理,页式管理是操作系统对内存和虚拟内存的一种逻辑组织和管理方式说得简单一些,操作系统将内存在逻辑上划分成固定大小的块(一般是4kb),当然虚拟内存(硬盘)也同样是如此划分,然后统一管理
对于程序就是根据块的大小来划分同样大小的页
我们知道像win或者linux可执行的程序都是存放在硬盘里的,那我们如何通过页来将程序加载到内存中呢
考虑一个问题:物理地址=块号*块长度+块内偏移
而页长度=块长度,块内偏移=页内偏移,最后就只剩下页号与块号对应了,当然是通过映射来决定的,这样问题就得到有效解决了
至于如何对应如何计算,给个链接参考一下:http://wenku.baidu.com/link?url=Mu9gPdoNJzRvF66rxZzLqZ1nmjVvjtF_I1_dYohld7nhEQRPeOnviyfXxogAtD9sIpC6f7HHjchIMoEGA14AnvDOkgEuGBqGZ9aLSQVQ--y
然后,考虑问题,为何要分段,原因总结起来就两点:1)方便S调度,2)内存安全访问
相比于页式管理,段式管理是以有逻辑意义为单位存储程序的,这样对于调度来说逻辑上要方便很多,特别是在动态链接时,会非常方便
从安全方便看,有些段在使用时会不断增长,事先不知道会增长到多大,如果采用连续空间的话会出现代码越界的问题,所以段式管理将段在逻辑上分开管理避免了访问越界的问题
最后说一下段页管理的综合使用,目前健全的OS都采用段叶式内存管理办法,一般是先将程序分段,然后再段内分页存储,然后按照段整体来调度,当然在实际调度中还是通过页表换如内存中的,只是调度是按照段来整体换入内存中的。
2.如何分段,各段的作用
有多种分类方法,就说一下说得比较多的5类吧分别是BSS段,数据段,代码段,堆和栈
其中BSS段是存放没有初始化的全局变量或者静态变量
数据段是存放初始化了的全局变量和静态变量
代码段是存放指令代码
栈由编译器自动分配释放,存放函数的参数值,局部变量的值等
堆是程序员分配和释放的,是动态内存空间,会随着程序运行变大或者缩小
这里说下我注意到的一个问题,就是在子函数(非main函数)中声明一个静态变量并初始化,那么这个变量的生命周期和作用范围到底是什么呢
生命周期是在被初始化开始到整个程序结束,而作用域是在该函数体类,所以在data区其实还有这样一类变量,虽然属于局部变量但是并不在栈中存储
最后说说字符串常量
在data区中有一类属于文字常量,字符串常量就存在此处,有时候也把这一类作为一类单独列出来
从上面可以得出结论,分段是根据生命周期来分类的,而作用域范围是标注的
相关文章推荐
- Hbase导入数据错误
- 了解传输的数据的新的类型(二进制)FlatBuffers
- 【iOS】网络操作与AFNetworking
- 系统吞吐量(TPS)、用户并发量、性能测试概念和公式
- try..catch..finally..
- 乐观锁和悲观锁
- Maven 2 + Hibernate 3.2 + MySQL Example (XML Mapping)
- BB-8机器人在美国亚马逊的买家评价
- 2013 ACM/ICPC Asia Regional Changchun Online
- 八皇后问题的递归求解
- 第5回 二弟呀,面子工程很重要
- SOAPUI----安全扫描(Security Testing)
- 23个设计模式
- UVA 818 Cutting Chains
- C#Socket通信
- Ajax提高篇(4)在请求和响应中使用 XML(2)
- Ajax提高篇(5)使用JSON 进行数据传输
- Ajax提高篇(6)服务器端脚本和程序中用 JSON 进行响应和回复
- Ajax提高篇(7)Ajax实现简单的下拉框联动显示数据
- UITableView 重用cell方法edequeueReusableCellWithIdentifier,出现错误