组装 - 堆对齐 - x86 intel

Posted

技术标签:

【中文标题】组装 - 堆对齐 - x86 intel【英文标题】:Assembly - Heap alignment - x86 intel 【发布时间】:2015-11-20 15:29:44 【问题描述】:

我想我理解堆栈对齐是 4 字节,例如如果我只添加一个字符,他的地址将在 4 字节的右侧(如果还有其他 1 或 2 字节变量,则稍早)

我仍然无法理解堆中的对齐方式,我认为有 4 字节或 8 字节对齐,但事情是这样的,当我分配 100 和 20 字节时,第一个结尾之间有 4 个字节和第二个的开头,所以我猜堆会使用 8bytes 对齐。

通过连续分配 1 4 7 8 9 14 16 17 个字节,我注意到 1、4、7、8、9 每个占用 16 个字节,而 14 16 17 占用 24 个字节,为什么会这样?

我正在使用 C/C++ 并使用 malloc 进行分配(与 new 相同)。

谢谢。

【问题讨论】:

可能取决于你如何分配这些东西,你没有展示出来。 对不起,我使用 C/C++,我用 malloc 分配它们。 【参考方案1】:

在 Windows 上,malloc 函数被记录为返回对齐 32 位应用程序的 8 字节边界和 64 位应用程序的 16 字节边界的内存。在 Linux 上,它只说它返回“适合任何类型的变量对齐的内存”,但它可能也是 8 和 16。

最重要的是,malloc 需要保留额外的内存来存储管理堆所需的跟踪数据。这意味着当您请求 N 个字节时,malloc 实际上将使用 N+X 个字节,其中 X 是常量并取决于实现。

【讨论】:

谢谢,我确实在使用Linux,分配1字节需要16字节(15个额外字节)而分配100需要104字节仍然很奇怪。管理堆的这些额外字节是否有名称,以便我可以做一些研究?或者你有任何文档页面吗? @x4rkz 大约1个字节需要16个,分配机制可能没那么简单。也许分配 104 或 105 字节将使用 112 ?如果是这种情况,也许附加数据也需要某种对齐方式。关于附加数据本身,我不知道它是如何工作的,但我认为它是指向某个 malloc 状态结构的指针。我不确定它有一个特殊的名字。 Windows x64 和 x86-64 System V ABI 都具有alignof(max_align_t) = 16 (godbolt.org/z/4dKhfeqhn),因此您可以保证从 malloc 中对齐(至少对于至少 16 个字节的分配;在理论上,较小的分配可能不太对齐,因为它无论如何都不能容纳 16 字节类型)。但是,是的,在 32 位代码中,malloc 可能只给你 8 字节对齐,或者如果没有任何带有alignof(T) == 8 的类型,理论上只有 4 个。 (大多数现代 32 位 x86 实现选择为性能提供 8,以防它用于 double 或其他东西。)【参考方案2】:

对齐只是某事物开始的位置:它的地址将是 A 的倍数。内存管理器将这些分配放在哪里,以及为什么,完全是它的业务,并且可能(部分)依赖于在您的程序之外的计算机中发生的其他事情。这意味着您无法通过“下一个”分配的位置来确定上一个分配的“大小”(虽然它可能在您的程序旁边,但它可能不在内存管理器旁边);事实上,“下一个”分配可能有一个较小的地址(例如,如果在此期间释放了较低的内存)。

【讨论】:

以上是关于组装 - 堆对齐 - x86 intel的主要内容,如果未能解决你的问题,请参考以下文章

如何组装和对齐svg?

x86 上未对齐的指针

堆分配变量的结构成员对齐

关于堆内存中的块对齐

分配粒度和内存页面大小(x86处理器平台的分配粒度是64K,内存页是4K,所以section都是0x1000对齐,硬盘扇区大小是512字节,所以PE文件默认文件对齐是0x200)

【译】JVM Anatomy Quark #24: 对象对齐