美文网首页
内存,地址,分页,指针

内存,地址,分页,指针

作者: Trigger_o | 来源:发表于2022-08-22 17:35 被阅读0次

系统总线
计算机系统总线分为数据总线,控制总线和地址总线.其中和内存相关的是数据总线和地址总线,有些cpu中,这两者甚至可以复用.

总线宽度
一条线同时只能传输一个bit,多条线就可以同时传输多个bit,有多少条线,叫做总线宽度.
总线带宽(即单位时间内可以传输的总数据数)为:总线带宽 = 频率 x 宽度 / 8,单位是字节/秒.其中频率是cpu的频率,比如1.5GHz.
而总线的宽度由CPU架构决定,也就是所谓8位,16位,32位,64位架构.64位的地址总线宽度就是64.64位的宽度,同时就可以传输64个bit(位).

寻址范围
在编程的时候接触的"内存"通常都是内存的地址,也就是编号.
CPU通过地址总线来传输内存的地址,64位总线一次可以传输64位的数据,也就是0000....0000(64位二进制) 到 1111....1111(64位二进制).
也就是说,64位的cpu它访问的地址,也就是2^64 这么多种组合,换成十进制就是0到2^64 - 1,必须在这之间,再多就不能访问了.

存储单元
内存的存储单元是字节,每个内存地址对应一个字节,也就是8位.两个连续的地址0x0001和0x0002之间隔了一个字节.

寻址空间
有了寻址范围,有了存储单元,那么寻址空间就是cpu能够访问的最大内存空间.
所以32位的寻址空间是2^32个组合 乘上 每个组合是一个字节,也就是2^32 字节,一个G是1024x1024x1024=2^30 ,所以32的寻址空间是2^32 / 2^30 = 4G,32位架构只能使用4G内存,再多也起不到作用.

内存地址
前面说到64位架构的寻址范围是64个0到64个1,所以内存地址就是64位二进制,换成16进制是16位.

虚拟内存
假如一台计算机的内存是2G.操作系统会给进程分配内存,不同的进程处在内存中不同的位置,叫做物理地址,并且还是动态的,非常复杂.
但是程序实际上并不关心物理地址,系统会给每个进程生成一份虚拟内存,这个虚拟内存的大小就是cpu架构的寻址空间,比如32位是4G.

虚拟内存

虚拟地址
虚拟内存的起始和结束地址都是固定的,以32位为例,是0x0000 0000到0xFFFF FFFF.
进程中的数据,对应的是虚拟地址,而数据真实存在的地方,也就是物理地址,由操作系统来负责做隐射,进程无需关心.
通常虚拟内存是比真实内存大的,尤其64位的寻址空间极大,有没有内存可用,系统自己知道.
不同的进程管理各自的虚拟地址,也就防止了进程之间互相访问和修改对方的内存.

虚拟内存结构

内存结构
这张图是x86的32位架构cpu虚拟内存结构.
每个进程都有一个虚拟内存,虚拟内存有很多分区,在上面这张图中,从下到上是内存低位到高位.
最高位的1G是内核空间,这部分的内容,每个进程都一样.
栈区位于比较高位,需要注意的是,特点是栈地址是由高向低分配,新入栈的数据,地址更低.栈区也是进程无法管理的.
堆区可以允许进程自由申请内存,是低位到高位增长的.
理论上堆区最高位到栈区最低位就是未分配的内存,可以由栈和堆随意使用,但是实际上栈区被限制只有几兆的大小,大部分未分配都是堆区.

内存分页
假设内存是连续分配的(也就是程序在物理内存上是连续的)
1.进程A进来,向os申请了200的内存空间,于是os把0~199分配给A
2.进程B进来,向os申请了5的内存空间,os把200~204分配给它
3.进程C进来,向os申请了100的内存空间,os把205~304分配给它
4.这个时候进程B运行完了,把200~204还给os,这5空间可能很长时间都会空着了.
因此系统必须支持不连续的内存分配.
但是不连续就得考虑效率问题,假如每个字节都这么精打细算,效率就太低了,因此现代CPU定义了MMU(Memory Management Unit 内存管理单元)的最小单元是4K,即4096个字节.叫做页.
MMU就负责将虚拟地址隐射到可能分布内存中各种地方的物理地址,一个进程被分割放在n个页中.
映射是一一对应的,虚拟内存中的4K,被映射到物理内存中的4K,虚拟内存中叫做页(page),物理内存中的叫做页帧(page frame),页和页帧是一样大的.这个隐射存储在内存里的页表中.

内存碎片
上面那个例子中,在分页机制中也会存在,只不过指定了最小单元后影响就小很多了,MMU的最小单元页的大小是4K,每个页里没用上的部分依然是内存碎片.

指针
指针是一个数据结构,它需要一块内存来存储,存储的内容,就是它所指向的地址.
所以指针存的也就是64位二进制,因此64位架构的指针所占的内存空间是8个字节.
这8个字节全部用来存储地址,也就是指针的值,至于指针的类型,是编译器的工作,并没有在内存中体现.

相关文章

  • 内存,地址,分页,指针

    系统总线计算机系统总线分为数据总线,控制总线和地址总线.其中和内存相关的是数据总线和地址总线,有些cpu中,这两者...

  • iOS底层原理--001:alloc & init

    内存地址 & 指针地址 搭建allocDemo项目打印对象的内存地址和指针地址- (void)viewDidLoa...

  • iOS指针

    OC中的内存地址:一:指针变量自己所在的内存地址(指针变量也是变量,也有内存地址)二:指针变量所指向的内容的内存地...

  • C语言指针

    指针的定义 指针的本质就是内存地址; 指针变量存储的是指针,也就是存储内存地址的变量; 在计算机世界中,内存地址其...

  • 2.7-C语言入门-指针

    1.指针的含义-变量的地址 a.指针:C语言中用“指针”来表示内存地址(即:指针指向了内存地址),即“指针”可理解...

  • C语言特性(指针)

    指针 指针的概念 简单来说,变量的内存地址就是该变量的指针;而用于保存内存地址(指针)的变量就是指针变量 指针变量...

  • C语言入门开发-指针

    指针1、认识指针[地址]内存每个直接都有一个唯一编号,称为地址[指针]存放数据的地址 变量与内存地址的关系1、变量...

  • C#指针

    指针基础 指针可以完成对内存地址的操作指针就是用来存储某个变量的内存地址 这时候输出pa就是输出a的内存地址 这时...

  • 集合和非集合的copy与mutableCopy

    名词解释:非集合类:浅copy(指针地址copy):指针地址不同,内存地址相同;深copy(内存地址copy):指...

  • C语言之指针[<重点>]

    指针:指针就是地址,地址就是指针。地址就是内存单元的编号。指针变量是存放地址的变量。指针和指针变量是不同的的概念。...

网友评论

      本文标题:内存,地址,分页,指针

      本文链接:https://www.haomeiwen.com/subject/dcyigrtx.html