10.25学习笔记

Redis内存管理涉及内存地址对齐,确保数据读取效率。内存分区包括栈、堆、全局区、文字常量区和代码区。zmalloc()函数在分配内存时考虑了8字节对齐,并通过update_zmalloc_stat_alloc更新内存使用统计,同时讨论了do{...}while(0)的用法。
摘要由CSDN通过智能技术生成

Redis

1.内存地址对齐

内存地址对齐,是一种在计算机内存中排列数据、访问数据的一种方式,包含了两种相互独立又相互关联的部分:基本数据对齐和结构体数据对齐。当今的计算机在计算机内存中读写数据时是按照字(word)大小块来进行操作的(在32位系统中, 数据总线宽度位32,每次读取4字节,地址总线宽度为32,因此最大的寻址空间为2的32次方=4GB,但是最低两位A[0],A[1]不用于寻址,A[2-31]才能与存储器相连,因此只能访问4的倍数的地址空间,但是总的寻址空间还是2的30次方*字长=4GB,因此在内存中所有存放的基本类型数据的首地址的最低两位都是0,除结构体中的成员变量)。

基本类型数据对齐就是数据在内存中的偏移地址必须等于一个字的倍数,按这种存储数据的方式,可以提升系统在读取数据时的性能。为了对齐数据,可能必须在上一个数据结束和下一个数据开始的地方插入一些没有用处字节,这就是结构体数据对齐。

假设计算机的字大小为4个字节,因此变量在内存中的首地址是满足4地址对齐,CPU只能对4的倍数的地址进行读取,而每次能读取4个字节大小的数据。假设有一个整型的数据a的首地址不是4的倍数,为0X00FFFFF3,则该整型数据存储在地址范围为0X00FFFFF3~0X00FFFFF6的存储空间里,而CPU每次只能对4的倍数内存地址进行读取,因此想要读取a的数据,CPU要分别在0X00FFFFF0和0X00FFFFF4进行两次内存读取,而且还要对两次读取的数据进行处理才能得到a的数据,而一个程序的瓶颈往往不是CPU的速度,而是取决于内存的带宽,因为CPU的处理速度要远远大于从内存中读取数据的速度,因此减少对内存空间的访问是提高程序性能的关键。因此采取地址对齐策略是提高程序性能的关键。

当结构体某一个成员后面紧跟一个要求比较大的地址对齐成员时,这时要插入一些没有实际意义的填充(Padding),而且总的结构体大小必须为最大对齐的倍数。

同样一个结构体,调整内部成员的顺序可以改变结构体的大小。

struct test1
{
    char c;
    short b;
    int i;
    char d;
}Node;

这个结构体在编译以后,为了字节对齐,会被整理成这个样子:

struct test1
{
    char c;
    char padding[1];
    short b;
    int i;
    char d;
    char padding[3];
}Node;

 编译后大小由8字节变成了12字节。如果顺序如下:

struct test2
{
    char c;
    char d;
    short b;
    int i;
}Node;

那么编译前后大小都是8字节。编译后不用填充字节就能保持所有的成员都按各自默认的地址对齐。这样可以节约很多内存,一般的结构体成员按照默认对齐字节递增或是递减的顺序排放,会使总的填充字节数最少。 

空结构体的空间是一个字节
struct s{};
sizeof(s);结果为1

有static的结构体
struct s
{
    char a;
    long b;
    static long c;
}
静态变量存放在全局数据内,而sizeof计算栈中分配的空间的大小,故不在计算内。该结构体大小为4+4=8。

2.内存分区

(1)栈区(stack):由编译器自动分配释放,存

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值