我之前遇到过这样的情况(问题的结构不长,但是为了解决问题,我将其更改):
创建一个结构以检查内存职业。在查看结果之前,首先计算:
如果计算出来,则结构的结构应为:15个字节正确。来打印:
32字节???这不是一个坑吗?记忆职业增加了一倍。
通过寻找信息,我发现了这样的名词:这是什么?
简而言之,当读取数据时,它不会由字节和字节读取,但它逐一读取。那么这是多少快?根据数字的数量,它是不同的。
当编译器编译时,为了确保内存对齐,对每种数据类型的对齐保证提供了保证,并留下未签名的内存。如果对齐保证为4B,则数据存储偏移的起始地址必须是4B的整数倍数。编译器给出了什么对齐保证?不同平台和不同平台的不同版本的编译器不同。您可以通过功能获得它。
通过分析先前的数据结果,您可以粗略地理解它。让我们看一下几种类型的对齐的值:
结果如下:
让我们在内存中一一尝试(下图中的每个空白代表一个字节):
1.放入:对齐保证为1,第一个变量,直接放置。
2.放入。对齐保证是4,这是一个整数倍数,两种偏移。在现有地址中,第四个整数倍数是第四个字节(中间三个字节为空)。
根据这个想法,将随后的变量顺序放置,结果占据的记忆是(依次占据字母,剩下简短):
但这是一个字节。它几乎是实际的32个字节。不用担心,看看结构结构的保证,发现它是8b。它不是上面8B的整数倍数。
这样,它正是32位。结构的结构,其成员变量的对齐保证的最大值。
那么,为什么编译器会进行这种记忆?例如,如果您不进行内存对齐,则以下结构的内存分布是:
还记得以前,您是否一一阅读记忆?假设是。
在这种情况下,当您需要读取变量时,需要执行两个内存访问。对齐后,您只需要执行内存访问即可。这是改变时间的典型空间。
现在您知道问题在哪里,如果您更改字段的顺序,可以压缩内存空间吗?
通过先前的对齐分析。结果是18b。这是因为该场的序列。为了确保记忆对齐,编译器填补了很多空白,从而浪费了内存。
只需修改字段的顺序,就可以直接减少结构的内存。
因此,有什么方法可以帮助我们检测到内存对齐的优化?毕竟,当您通常写作时,谁会关心这些东西?更不用说,确实有。
官方网站:https://golangci-lint.run/
安装:
检测所有文件命令:
检测初始结构文件(添加参数指定的检测内存对齐):
看到结果:
您将看到该结构当前占据32B的提示,可以优化为16B。完美的。
当然,该工具的功能不仅在内,还可以提供许多建议,即被挖掘。
实际上,据估计,很少有时间注意记忆的记忆。
原始:https://juejin.cn/post/7102573418549084190