【问题标题】:Running out of space after allocating only ~1400MB when free space beforehand was significantly greater当预先分配的可用空间明显更大时,仅分配 ~1400MB 后空间不足
【发布时间】:2016-03-25 13:14:25
【问题描述】:

我编写了一个 C 程序,使用链表完全填满 ram,以查看我使用的操作系统如何处理它。

程序和资源管理器的屏幕截图: http://i.imgur.com/s6OQRBG.png

我在 virtualbox 中运行 kali linux,操作系统仅使用 700-ish MB,因此可用空间接近 3 gigs ......但是在我的程序中仅分配 1420MB 后内存就被填满了。代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

typedef struct node
{
  char val;
  struct node *next;
} node_t; // 16 bytes according to sizeof()

node_t *create_node(node_t *current, char newval)
{
  node_t *head = malloc(sizeof(node_t));
  head->val = newval;
  head->next = current;
  return head;
}

int main(void)
{
  node_t *head = NULL;

  for ( int i = 0; i < 1099511627776; i++ ) //arbitrarily large number
  {
    for ( int j = 0; j < 65536; j++ ) //64*1024
    {
      head = create_node(head, 'a');
    }
    usleep(11111);
    printf("%dMB\n", i+1);
  }

  return 0;
}

64 个节点应该是一千字节 (16*64 = 1024),而 1024 KB 应该是一个 MB... 那么为什么我的内存在分配了大约 1400MB 之后就被填满了呢?

【问题讨论】:

  • 而 malloc 保留了分配更多的灵活性,所以不要指望在分配小块的次数过多时内存会被完全使用。
  • @user3528438 已修复,必须从 virtualbox 手动复制代码,因为我无法共享剪贴板或拖放工作
  • node_t; // 16 bytes according to sizeof() malloc() 开销可能在同一范围内,有效地使您的内存消耗加倍。 -->> 避免许多*小的分配。
  • 哇为什么会有这么大的开销?
  • @joop 每次分配 16 字节开销?!?那将是一个非常糟糕的分配器。我知道使用可用空间来存储簿记信息(dlmalloc)的实现。虽然可能与强化实施有关?

标签: c linux memory virtualbox


【解决方案1】:

你很有可能正在分割记忆。

考虑到一个内存页明显大于 16 字节,并且您分配 16 字节 x 16 字节,您最终可能会得到 2048 或 4096 字节的内存页,而仅使用了 16 字节(或更多,但绝不会全部使用)页)。

如果您想要更好的内存基准测试,请在连续空间中分配字节数组(还要确保通过写入来提交内存)。

【讨论】:

  • 如果我理解正确,操作系统会逐页为进程提供内存,但进程不应该在分配另一个页面之前用完该页面吗?为什么不/不呢?
  • 实际上操作系统一次给进程多个页面,不知道这些页面是根据什么算法给出的。当进程决定分配一个小对象(例如您的)时,它将从一个可用页面中选择并将其存储到该页面中,以及一些开销。在分配的某个时间,进程可能会决定它需要更多页面,并要求操作系统增加它的内存,然后这将失败。做一个快速实验并在指针之间进行算术差异。您会注意到它们之间的距离不是 16 个字节。
  • 但是为什么进程在请求更多之前不先用完它给定的空间,以至于程序占用了它应该占用的几乎两倍的空间?
猜你喜欢
  • 1970-01-01
  • 2019-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-21
  • 2013-10-12
  • 1970-01-01
  • 2015-05-02
相关资源
最近更新 更多