关于内存对齐的博客,网上可以搜到很多,但是大多讲述的都是关于内存对齐的规则,所以本篇文章就不再继续介绍了,而至于为什么要进行内存对齐,如果细心的网友有进行过大量的搜索一定会发现,下面这段话是大家经常见到的:
1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据,某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2、性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,对于访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
如果你在其它地方多次看到了这样的结论,但是对于上述两点又并没有很理解,没关系,接下来,我们再为大家简单的介绍一下,相信大家就能对上面的两句话有了进一步的认识了。
我们知道,在内存中,存储空间是按照一个字节一个字节排列的,但这样的描述其实是说给我们广大的程序员听的,对于CPU来讲,它并不清楚。对于不同的硬件平台,它们可能在读取内存的时候是按照2个字节、4个字节、8个字节、16个字节或者32个字节这样的存取方式来访问内存的,也就是说如果你的内存没有对齐,举个例子,有一个int类型的变量,占用4个字节,假设它从0地址开始存储,即编号为0,1,2,3这四个字节就存储下了这个int变量,又假如我们的cpu是按照4个字节的方式读取内存,那么正好经过一次就能拿到这个变量的值;如果int变量存放在了1,2,3,4这4个字节的位置,那么问题就来了,第一次我们读取4个字节编号为0,1,2,3;发现并不能正常获取这个值,于是我们继续往后读取,4,5,6,7;此时我们进行了第二次读取,一共堵了8个字节,终于在这8个字节里找到了对应的这个int变量。于是,在这种情况下,我们的内存访问效率显然就变低了,也就是性能变低了。而第一条说白了则讲的是不同平台下不同数据类型大小不一定一致的问题,如果内存没有对齐,则cpu可能不能访问到正常的数据,而内存对齐则可以避免这个问题。比如32位下的一个结构体,拥有一个字符型,和一个int类型的指针,假设地址从0开始,则char类型占据0地址,1,2,3空余,4,5,6,7存放int类型指针,结构体一共占用8个字节;当这个结构体移植到64位平台下,则char类型占据0地址,1-7空余,8-15存放int类型指针一共占用16个字节。通过内存对齐的偏移量,我们可以很好的找到这个int类型指针的位置。而如果没有内存对齐,32平台下的结构体成员挨着存放,无论是在32平台下,还是移植到64位平台下,对于int类型指针的访问都是一件复杂且容易出错的问题。