Linux内存管理开销

4

我正在尝试解释在Linux中我的应用程序所占用的内存。我进行了一项基本测试,发现如果我们使用new命令申请内存,则至少为单个new分配了32字节。

以下是我的代码。

#include <iostream>
#include <stdlib.h>

using namespace std;

int main(int argc, const char** argv)
{
        int iBlockSize = atoi(argv[1]);
        int iBlockCount = atoi(argv[2]);

        for (int i = 0 ; i < iBlockCount ; i++)
        {
                cout << (int*)(new char[iBlockSize]) << endl;
        }
        return 0;
};

当我执行./a.out 8 100时,它给出了以下结果。
....
....
....
0xf6db10
0xf6db30
0xf6db50
0xf6db70
0xf6db90
0xf6dbb0
0xf6dbd0
0xf6dbf0
0xf6dc10
0xf6dc30
0xf6dc50
0xf6dc70

我拥有的所有内存都有32字节的间隙。

直到24(BlockSize),它是相同的。如果超过24,则为48个字节。

./a.out 25 100

....
....
....
0x18b30c0
0x18b30f0
0x18b3120
0x18b3150
0x18b3180
0x18b31b0
0x18b31e0
0x18b3210
0x18b3240
0x18b3270
0x18b32a0

当我测试更大的尺寸时,发现我们获得的内存是以16字节块增加的,至少保留8字节的开销。

我的问题是:

  1. 我的测试正确吗?
  2. 这是Linux内存管理的正确行为吗?
  3. 如果我们申请了8个字节,我们会得到32个字节。其他24个字节去哪了?被重复使用还是分裂成开销?

3
总会存在预先分配的开销。而分配数组通常需要在某处存储其大小,这通常是存储在数据本身附近的位置。 - leemes
3个回答

6
在类似C语言的编程语言中,内存分配必须为所有原始类型返回适当对齐 [0] 的内存。
这意味着内存分配通常会给你至少8字节对齐的内存,以便您可以在其中存储doubles
因此,当您请求1字节的内存时,由于对齐要求,您将使用至少8字节的内存。在64位系统上,由于这些系统通常具有16字节大的类型(SSE向量),内存分配通常会给您16字节对齐的内存。
此外,内存分配器需要一些空间来存储其管理数据,例如分配的大小。根据实现,该数据可以放置在用户分配的内存块之前或之后。
[0] 当地址/指针以访问其大小的倍数访问时,内存被对齐,一些CPU不支持非对齐访问(例如sparc),其他CPU(如x86)可能会对此产生性能惩罚。

感谢jtaylor的解释。无论如何,如果内存元数据(管理数据)也保存在同一位置。如果我们错误地写出了边界,那么会影响内存管理模块吗? - Sujith Gunawardhane
我用memset测试了相同的代码,该代码使用new char [8]分配的32个字节。然后程序在delete[]处崩溃(*** glibc detected *** ./a.out: free(): invalid next size (fast): 0x0000000000603fa0 ***),而不是在memset处。这说明内存管理数据也与内存本身一起保存。如果我删除delete[],即使分配和写入千兆字节的内存,程序也可以正常运行,没有任何错误。 - Sujith Gunawardhane
管理数据存储的位置是实现细节,取决于您使用的malloc。例如,glibc具有特殊的malloc调试标志(例如MALLOC_CHECK_通常默认启用),这将导致它检查其内部数据是否存在不一致性,这就是为什么您在删除时看到崩溃但在memset上没有的原因。 - jtaylor

2
与该主题相关的C ++标准中的几行代码,我认为它简要描述了这不是错误行为。

在C ++程序中定义的任何分配和/或释放函数(包括库中的默认版本)都应符合3.7.4.1和3.7.4.2中指定的语义。...

3.7.4.1分配函数...返回的指针应适当对齐,以便可以将其转换为具有基本对齐要求(3.11)的任何完整对象类型的指针,并且...

3.11对齐对象类型具有对齐要求(3.9.1、3.9.2),它们对可以分配该类型对象的地址施加限制。对齐是一个实现定义的整数值,表示给定对象可以分配的连续地址之间的字节数。...


1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接