c++ - 使用 valgrind 进行堆分配

标签 c++ memory valgrind allocation

const size_t size = 10000000;
using T = unsigned short[];
vector<unique_ptr<T>> v;
v.resize(size);
for (size_t n = 0; n != size ; ++n) {
  v[n] = make_unique<T>(3);
  for (int i = 0; i!= 3; ++i)
    v[n][i] = rand();
}
我想测量它使用了多少内存。
  • 我的期望: 10.000.000*(8+2*3) = 140.000.000 字节。每个指针 8 个字节,每个 unsigned short 2 个字节。
  • "valgrind -- --tool=memcheck"返回:总堆使用量:10,000,112 次分配,10,000,111 次释放,140,161,828 字节分配
  • 它实际上是: VIRT = 419044,RES = 394180 (KB)。

  • 为什么实际尺寸是 valgrind 显示器的 3 倍?
    我在 VSL、ubuntu 上运行它。

    最佳答案

    您忘记了内存分配本身的开销。只需 new/delete本身:有东西必须跟踪它。某处。
    您很容易,但 C++ 库会为您完成所有艰苦的工作。
    你很容易:你只需new一些任意数量的字节,和delete稍后,你就完成了。但对于 C++ 库来说,这并不容易。它必须知道每个有多大new ed 对象或对象是。所以当他们是 delete d C++ 库知道刚刚删除了多少内存。当内存中的相邻对象得到delete d,分配器也需要意识到这一点,并将两个相邻的 delete 结合起来。 d 个对象合并到一个更大的内存块中,以便它可以潜在地用于 new一个更大的物体,在稍后的某个时间点。
    这种复杂性不是免费的。需要对其进行跟踪和汇总。
    所有这些爵士乐都至少需要一个指针值和一个字节计数值。按分配。一个健壮的内部内存分配器可能希望在某个地方存储一个额外的指针,但让我们从一个指针和一个字节数开始,作为内存分配器的一个极简实现。
    您正在分配 sizeof(unsigned short)*3一次字节,或者按我的计数为 6 个字节。在 64 位平台上,指针需要 8 个字节长。假设您有一个智能内存分配器,它维护一个单独的 bool 分配,其大小不超过 64kb,因此内存字节数只需 2 个字节。所以这是每次分配十字节的开销。
    该开销需要存储、跟踪并堆积到 分配。因此,考虑到每分配 6 个字节至少有 10 个字节的额外开销,观察到使用 2-3 的预期内存量似乎几乎在球场上。如果字节计数在内部被跟踪为 4 个字节,或者如果内存池是双向链表,则肯定在球场上,需要 另一个 8 个字节(如果幸运的话,可能是 4 个字节)混在一起。

    关于c++ - 使用 valgrind 进行堆分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65790333/

    相关文章:

    c++ - 我如何在 BCrypt 中使用带有 secret 的 AES-GMAC?

    memory - 为什么启用/禁用A20线

    memory - 如何实现/设置数据断点?

    C++ 赋值构造函数 Valgrind 错误

    c++ - 这个 valgrind 在 crypto++ 中使用大小为 8 的未初始化值是真实的还是红鲱鱼?

    c++ - 使用 valgrind 查找 mysql c++ 客户端中的内存泄漏

    java - 使用 if(0 == foo()) 而不是 (foo() == 0) 有什么好处?

    c++ - 我无法弄清楚为什么在使用 ifstream 时出现段错误

    c++ - 代码正在打印对象的内存位置而不是对象本身

    c - 从输入插入数组中的元素 [核心转储(段错误)]