内存(RAM)结构[物理级] malloc()实际分配给用户的内存

大多数为刷牙时的猜测,若有读者请慎之。


猜的目的:搞清存储器在不同位数系统中的结构;malloc()函数返回给用户的实际内存块。


1 半导体存储体在以字节为存储单元的系统中的结构

半导体存储体由存储单元构成,存储单元由存储元件构成。此处略存储器内的其它电路模块。


(1) 存储元件

存储器用于寄存“0”和“1”代码的电路称为存储器的基本单元电路(存储元件)。分SRAM和DRAM基本单元电路。如单管MOS DRAM基本单元电路:


Figure1. 单管MOS DRAM基本单元电路

字线上的高电平使T导通(MOSFET元件),若C有电荷,经T管在数据线上产生电流,可视为读出“1”。若C上无电荷,则数据线上无电流,可视为读出“0”。


(2) 存储单元

存储元件的“0”、“1”状态能表示的对象有限。多个存储元件的“0”、“1”状态组成序列(串)就能够表示某对象或集合(如7个存储元件的状态就能够表示所有的ASCII)。或许是比较符合实际需求的原因,8个存储元件被视为存储器的最小存储单元,所有的其它的存储单位(如int类型)都由存储单元(即字节)组成(其实在多个字节中的各字节不在同一块内存中)。


一个存储单元由8个诸如Figure 1中的存储元件构成。


Figure2. (字节)存储单元结构


(3) 以字节为单位的存储器芯片

[线选法]

Figure3. 以字节为单位的存储器芯片

Figure 3中省略译码器、驱动器、读\写及控制等具体的电路。Figure3中所示Lxr-xxxxxx信号存储芯片大小为28 bytes即256字节。每个存储单元地址被选中时,这个存储单元就和数据线(D0 – D7)进行数据交互。如译码器输入端输入(00000000)2时,第0行存储单元被选中,第一行即和数据线交互数据。


以字节为存储单元的存储器本身就可以被做的很大。也可以由小容量存储芯片组成容量更大额存储器芯片(字扩展),如:

Figure4. 以字节为单位存储器的字扩展
10地址线为0时,右边的存储器芯片被选中,与数据线交互的是右边的存储器,地址范围为[0,(01111111) 2]。10地址线为1时,左边存储器被选中,与数据线交互的是左边的存储器,地址范围为[(10000000) 2, (11111111) 2]。Figure 4存储器寻址范围为[0, 11111111],是原来单个存储器的2倍。

(4) 多字节存储器芯片(位扩展)

以16位(2字节)为例(但一般的计算机的存储单元都是8位)。

Figure5. 位扩展的16 bit存储器芯片

每一个地址都能对应16位数据。不过一般是将位数更小的来构成8位宽度的存储器。像这样构成16位的存储器后,就没法访问一个字节。


(5) 内存单元为8位的16位系统

CPU 16位的数据总线需要接两块以字节为单位的存储器,这样才有可能实现一次访问到16位数据或8位数据。


现用两块27 * 8位存储器和具16位数据总线的CPU相连,让CPU既能一次访问8位,也能一次访问16位。

Figure6. 内存单元为8位的16位系统

如图Figure  6,A0为0且B=0时存储器1被选中,此存储器的地址全是偶数,且标识一个字节。B = 1且A0 = 1时存储器2被选中,此存储器的地址全是奇数,且标识一个字节。当A = 0且 B = 1时,两个存储器都被选中,此时用偶数地址标识存储器上的两个字节即16位。


可按照相同方式得32位系统存储器结构:

Figure7. 32位系统以字节为单位的存储器结构

根据Figure 7讨论内存对齐。由于内存对齐,每个变量存储的起始地址都有讲究。若有一个变量占用4个字节,那么此变量就被分配到地址为4的整数倍的某个地址上,且再连续占4个字节。若有一个变量占用1个字节,那么这个变量随便保存到哪里都可以。


如果占用4个字节的变量的地址非自身的整数倍,那么这个变量会被存到内存中相邻的两行里, 则访问这个变量需要往地址线上送两次地址且还需要将两次访问回来的数据作处理(恢复其高低位关系)才能得到正确的数据。

2 malloc()分配的内存块结构

Figure8. malloc()分配的堆空间的结构

(1) malloc()分配的内存块的长度

malloc(size)函数所分配内存的长度为Header部分长度的整数倍(请求的长度(字节为单位)将被舍入,以保证它是头部大小的整数倍,即实际分配的内存大于等于size字节)。


(2) 给用户的内存空间

malloc()函数返回给用户的空间是Header后面的内存空间,见Figure8。


(3) Header结构

[1] Header有一个指向空闲块链表中下一块的指针ptr变量。还有一个包含本块内存大小的size变量。

[2]为确保malloc()函数返回的存储空间满足将要保存对象的内存对齐要求,就在Header中保存一个最受限制(占内存最大)的类型的变量。如:Header为8个字节,则Header定被保存在自己的内存边界上先满足内存对齐的要求,再加上用户空间是Header的整数倍,从而使不管保存什么样的类型的变量都能达到内存对齐的目的。

Header的结构可以描述如下:

typedef  double Align //假设double为占内存最大的类型

union header {

        struct {

               union header  *ptr;

               unsigned  size;

        }s;

        Align x;

}

x和s占相同的一块存储空间。x仅用于强制每个头部在最坏的情况下都满足内存对齐要求。在用户空间为Header大小整数倍的情况下,使用户空间也满足内存对齐(就算存储x类型变量都可以满足内存对齐要求)。


(4) malloc()实际分配给用户的内存

Header的ptr和size帮助内存的分配和释放。x确保用户空间所要保存的对象满足内存对齐。

由于于x的存在,在32位系统中(Figure 7中的存储器结构(忽略虚拟内存层)),当调用malloc(size)分配内存时,Header会占用sizeof(Header)字节,且起始地址为sizeof(Header)的整数倍。分配给用户的内存空间取决于(float)size / sizeof(Header) = r .k的值。

  • 若k = 0,则返回给用户的内存大小为size 字节;
  • 若k 不等于0,则返回给用户内存大小为(r+ 1) * sizeof(Header)字节。


[2014.11.7 -- 22:28]

R《TCPL》、《CC》 Note Over.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值