Linux内存管理开销

时间:2014-07-10 17:49:04

标签: c++ linux memory

我试图解释在Linux中对我的应用程序采取的内存。我做了一个基本测试并发现如果我们新建一些内存,它会为一个新的内存分配至少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 个答案:

答案 0 :(得分:6)

C语言中的内存分配必须为所有基本类型返回适当对齐的内存[0]。 这意味着内存分配通常会为您提供至少8字节对齐的内存,因此您可以在其中存储doubles

因此,当您请求1字节内存时,由于对齐要求,您将使用至少8个字节。 在64位系统上,内存分配通常会为您提供16字节对齐的内存,因为这些系统通常具有16字节大型(SSE向量)

此外,内存分配器需要一些空间用于其管理数据,例如分配的大小。 根据实现情况,可以在用户分配的内存块之前或之后放置此数据。

[0]当地址/指针是访问它的大小的倍数时,内存是对齐的,某些cpus不支持未对齐访问(例如sparc),其他(如x86)如果你这样做会有性能损失

答案 1 :(得分: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),这些要求对可以分配该类型的对象的地址施加限制。对齐是实现定义的   整数值,表示连续之间的字节数   可以分配给定对象的地址。 ...

答案 2 :(得分:1)

我找到了这篇文章

https://software.intel.com/en-us/articles/align-and-organize-data-for-better-performance

它说“如果使用向量指令加载和存储来访问数据,则将数据对齐在16字节边界上。”

所以看起来这是由glibc做出的对齐决定