首页 > 系统相关 >内存对齐

内存对齐

时间:2023-02-18 19:55:12浏览次数:73  
标签:struct 内存 规则 对齐 sizeof pack

内存对齐是什么?

对结构体和类来说,让变量不是紧挨着存放,而是通过变量字节倍数的形式存放

为什么会有内存对齐?

  • 增加cpu的访问数据的速度
    • 对于cpu来说,数据从内存中读到缓存中去,是通过偏移量(offset)进行读取,也就是常说的通过块来读取,而不是按照字节读取。
    • 读取非内存对齐的数据,会出现一次必须读取offset和offset+1两块数据这种情况,这需要为芯片增加额外的加法器( 为了得到offset+1 )。为了上述这种可能,而增加额外的设备,并且每一次的增加访问时间,显然是不明智的
    • 还有一点就是读了两次,读到缓存的位置上也需要两次,同样降低效率
  • 方便于不同机器、不同平台进行数据的准确读取

内存对齐规则

  • 规则1:需要按照min(pack,sizeof(变量本身))的倍数进行选择开始位置

  • 规则2:整体按照min(pack,sizeof(字节数最大的变量))的倍数进行计算

  • 规则3:数组则按照本身是哪种类型变量进行计算,同样遵循规则1

  • 规则4:结构体中的结构体X,X内部遵循规则1计算大小,并且选择位置也遵循规则1

  • 注意:

    • 规则1和2,为主要原则,3和4作为拓展
    • sizeof得到所占字节数,pack为对齐模数
    • 查看对齐模数#pragma pack(show),编译时会显示

案例

运行环境:Microsoft Visual Studio Community 2022 (64 位) - Current版本 17.3.4
对齐模数:#pragma pack(show) == 16

  • 案例1
pack == 16
struct A{
	char a;	//0-3
	int b;	//4-7
	double c;//8-15	
};  //	16/8 可除
规则1:需要按照min(pack,sizeof(变量本身))的倍数进行选择开始位置
规则2:整体按照min(pack,sizeof(字节数最大的变量))的倍数进行计算
pack == 2
struct B{
	char a;	//0-2
	int b;	//2-5
	double c;//6-13
};  //	14/2 可除
规则1:需要按照min(pack,sizeof(变量本身))的倍数进行选择开始位置
规则2:整体按照min(pack,sizeof(字节数最大的变量))的倍数进行计算
  • 案例3
pack == 16
struct C{
	char a;	//0-1
    short b[3];//2-7 --->the place
	int c;	//8-15
	double d;//16-23	
};  //	24/8 可除
规则3:数组则按照本身是哪种类型变量进行计算,同样遵循规则
  • 案例4
pack == 16
struct D{
	char a;	//0-7
    struct C b;//8-31
	int c;	//32-39
	double d;//40-47
};  //	48/8 可除
规则4:结构体中的结构体X,X内部遵循规则1计算大小,并且选择位置也遵循规则1
pack == 2
struct D{
	char a;	//0-1
    struct B b;//2-15
	int c;	//16-19
	double d;//20-7
};  //	28/2 可除
规则4:结构体中的结构体X,X内部遵循规则1计算大小,并且选择位置也遵循规则1

其他的注意

  • 空类和空结构体的sizeof大小为1

  • 该环境下指针的大小为8个字节

类与内存对齐

参考

参考资料:浅谈CPU内存访问要求对齐的原因 – 仰望苍天思寰宇 (yangwang.hk)

标签:struct,内存,规则,对齐,sizeof,pack
From: https://www.cnblogs.com/zqurgy/p/17133404.html

相关文章

  • 简单聊聊Azure VM的内存指标
    今天简单来聊下AzureVM内存指标的一些事,总体来说没什么深度,只是一些常见问题的分析和总结首先来说想看内存数据的话肯定是要安装agent的,否则没办法收集到内存数据,这一点各......
  • 计算机的数据算法-内存|顺序表|链表|单链表|双端链表
    内存计算机的作用用来存储和运算二进制的数据问题:计算机如何计算1+2?将1和2的二进制类型的数据加载到计算机的内存中,然后使用寄存器进行数值的运算变量......
  • JavaScript中数组是如何在内存中存储的?
    前言大家好,我是CoderBin,本次讲讲JavaScript中数组是如何在内存中存储的,希望对大家有所帮助,谢谢。如果文中有不对、疑惑的地方,欢迎在评论区留言指正......
  • MAT分析堆内存占用
    MAT介绍MAT是MemoryAnalyzertool的缩写,是一种快速,功能丰富的Java堆分析工具,能帮助你查找内存泄漏和减少内存消耗。很多情况下,我们需要处理测试提供的hprof文件,分析内存......
  • volatile的实现原理-内存屏障
     被volatile修饰的变量在编译成字节码文件时会多个lock指令,该指令在执行过程中会生成相应的内存屏障,以此来解决可见性跟重排序的问题。内存屏障的作用:1.在有内存屏障......
  • 指针,动态内存的例子
    #include<stdio.h>int*pPointer;voidSomeFunction();{intnNumber;nNumber=25;//makepPointerpointtonNumber:pPointer=&nNumb......
  • C语言之内存讲解
    目录1内存讲解1.1作用域1.1.1局部变量1.1.2静态static局部变量1.1.3全局变量1.2内存布局1.2.1内存分区1.2.2代码区(textsegment)1.2.3全局初始化数据区/静态数据区......
  • PHP超低内存遍历目录文件和读取超大文件
    前言这篇笔记主要解决这么几个问题:PHP如何使用超低内存快速遍历数以万计的目录文件?PHP如何使用超低内存快速读取几百MB甚至是GB级文件?顺便解决哪天我忘了可以通过搜索引擎......
  • java中的数据类型及内存分析
    1. java中的类型           (1)除基本类型之外的变量类型都称之为引用类型。   (2)java中的变量        ①局部变量:使用前必须被......
  • JVM内存模型分析
    JVMJVM内存模型解析JVM内存模型:https://juejin.cn/post/7024358170642350093https://www.cnblogs.com/blknemo/p/13296007.html线程独占:JVM栈,本地方法栈,程序计数......