内存对齐,只要是跨平台的都要内存对齐

博客围绕内存对齐和C++内存管理展开。介绍了C++、Java、Python的内存管理方式,指出C++需手动管理堆内存易造成泄漏。还说明了计算程序内存占用的要点,强调内存对齐对跨平台编程的重要性,解释其原因并对比了对齐与非对齐的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内存对齐

内存对齐,只要是跨平台的都要内存对齐,c\c++\java\python

其中c\c++是手动释放内存堆空间 动态开辟或new出来的。
jvm是java自动释放内存堆管理。但是有些错误的写法会照成内存泄漏,或内存溢出。
python 内存是由私有堆空间管理的,所有python对象和数据结构,都存在私有堆空间,程序员没有访问私有堆的权限,只有解释器才能操作。
python 万物皆为对象,对内存封装的很好,所以python的基本数据类型所用的内存,远大于存放纯数据类型所占用的内存,

c++内存管理

如果我们写C++的程序,就要知道栈和堆的概念,程序运行时所需的内存空间分为 固定部分,和可变部分,如下:
固定部分的内存消耗 是不会随着代码运行产生变化的, 可变部分则是会产生变化的
在这里插入图片描述

栈区(stack):由编译器自动分配释放。存放函数的参数值,局部变量的值,操作方式类似于数据结构中的栈。
堆区(heap):一般由程序员释放,程序员不释放,程序结束的时候可能会被OS操作系统收回。
未初始化的数据区(uninitiated Date):存放未初始化的全局变量和静态变量
初始化的数据区(initialized Date):存放已经初始化的全局变量和静态变量
程序员代码区:存放函数体的二进制代码。
代码区和数据区所占空间都是固定的,而且占用的空间非常小,那么看运行时消耗的内存主要看可变部分。
在可变部分中,栈区间的数据在代码块执行结束之后,系统会自动回收,而堆区间数据是需要程序员自己回收,所以也就是造成内存泄漏的发源地。
而Java、Python的话则不需要程序员去考虑内存泄漏的问题,虚拟机都做了这些事情。

如何计算程序占用多大内存

想要算出自己程序会占用多少内存就一定要了解自己定义的数据类型的大小,如下:
在这里插入图片描述
注意图中有两个不一样的地方,为什么64位的指针就占用了8个字节,而32位的指针占用4个字节呢?因为32位操作系统,地址总线就是32位的 寻址范围为2^32,为4G即:可以寻找4G空间大小的内存地址。,超过4G就寻不到了,所以现在大家现在使用的计算机一般都是64位了,所以编译器也都是64位的。
注意2^64是一个非常巨大的数,对于寻找地址来说已经足够用了。

内存对齐

不要以为只有C/C++才会有内存对齐,只要可以跨平台的编程语言都需要做内存对齐,Java、Python都是一样的。而且这是面试中面试官非常喜欢问到的问题,就是:为什么会有内存对齐?
主要是两个原因
1、平台原因:不是所有的硬件平台都能访问任意内存地址上的任意数据,某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。为了同一个程序可以在多个平台运行,需要内存对齐。
2、硬件原因:经过内存对齐之后,cpu访问内存的速度大大提升。
可以看一下这段C++代码输出的各个数据类型大小是多少?

struct node{
int num;
char cha;
}st;
int main() {
int a[100];
char b[100];
cout << sizeof(int) << endl;
cout << sizeof(char) << endl;
cout << sizeof(a) << endl;
cout << sizeof(b) << endl;
cout << sizeof(st) << endl;
}
4
1
400
100
8
在这里插入图片描述

为什么st内存大小为8?
他不是一个整形+一个字符型嘛?
5?
no ,他是8;
因为内存分配是一块一块分配的!

此时会发现,和单纯计算字节数的话是有一些误差的。

这就是因为内存对齐的原因。
来看一下内存对齐和非内存对齐产生的效果区别。
CPU读取内存不是一次读取单个字节,而是一块一块的来读取内存,块的大小可以是2,4,8,16个字节,具体取多少个字节取决于硬件。 (像上面的结果 就是快的大小4个字节,而不是2个字节 要不然就为6了)
假设CPU把内存划分为4字节大小的块,要读取一个4字节大小的int型数据,来看一下这两种情况下CPU的工作量:
在这里插入图片描述
一字节的char占用了四个字节,空了三个字节的内存地址,int数据从地址4开始。
此时,直接将地址4,5,6,7处的四个字节数据读取到即可。
第二种是没有内存对齐的情况如图:

在这里插入图片描述
char型的数据和int型的数据挨在一起,该int数据从地址1开始,那么CPU想要读这个数据的话来看看需要几步操作:
1因为CPU是四个字节四个字节来寻址,首先CPU读取0,1,2,3处的四个字节数据
2CPU读取4,5,6,7处的四个字节数据
3合并地址1,2,3,4处四个字节的数据才是本次操作需要的int数据
此时一共需要两次寻址,一次合并的操作。
此时一共需要两次寻址,一次合并的操作。

大家可能会发现内存对齐岂不是浪费的内存资源么?

是这样的,但事实上,相对来说计算机内存资源一般都是充足的,我们更希望的是提高运行速度。
编译器一般都会做内存对齐的优化操作,也就是说当考虑程序真正占用的内存大小的时候,也需要认识到内存对齐的影响。

五级标题
六级标题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值