Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 仅分配约1400MB后空间不足,而之前的可用空间明显更大_C_Linux_Memory_Virtualbox - Fatal编程技术网

C 仅分配约1400MB后空间不足,而之前的可用空间明显更大

C 仅分配约1400MB后空间不足,而之前的可用空间明显更大,c,linux,memory,virtualbox,C,Linux,Memory,Virtualbox,我编写了一个C程序,使用链表完全填充ram,以查看我使用的操作系统将如何处理它 程序和资源管理器的屏幕截图: 我在virtualbox中运行kali linux,操作系统只使用了700MB,所以可用空间接近3千兆。。。然而,在我的程序中只分配了1420MB之后,内存就满了。代码如下: #include <stdio.h> #include <stdlib.h> #include <unistd.h> typedef struct node { char

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

程序和资源管理器的屏幕截图:

我在virtualbox中运行kali linux,操作系统只使用了700MB,所以可用空间接近3千兆。。。然而,在我的程序中只分配了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;
}
#包括
#包括
#包括
类型定义结构节点
{
char-val;
结构节点*下一步;
}节点_t;//根据sizeof()的16个字节
节点\u t*创建\u节点(节点\u t*当前,char newval)
{
node_t*head=malloc(sizeof(node_t));
head->val=newval;
head->next=当前;
回流头;
}
内部主(空)
{
节点头=空;
对于(int i=0;i<109951162776;i++)//任意大的数字
{
对于(int j=0;j<65536;j++)//64*1024
{
head=创建_节点(head,'a');
}
usleep(11111);
printf(“%dMB\n”,i+1);
}
返回0;
}
64个节点应该是一个KB(16*64=1024),1024KB应该是一个MB。。。
那么,为什么我的ram在只分配了约1400MB的内存之后就被填满了呢?

很有可能是内存碎片

考虑到一个内存页比16字节大得多,并且您正在分配16字节乘以16字节的内存页,您可能最终拥有2048或4096字节的内存页,并且只使用了16字节(或更多,但永远不会使用整个页面)


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

并且malloc保留分配更多内存的灵活性,因此当您分配小块太多次时,不要期望内存被充分利用。@user3528438 fixed,必须从virtualbox bc手动复制代码我无法获得共享剪贴板或拖放工作
node\u t;//根据sizeof()的规定为16字节。
malloc()开销可能在相同的范围内,实际上是内存消耗的两倍。-->>避免很多*小的分配。哇,为什么会有这么大的开销?@joop每个分配16字节的开销?!?这将是一个非常糟糕的分配器。我知道一些实现使用空闲空间来存储簿记信息(dlmalloc)。虽然可能与强化的实现有关?如果我理解正确,操作系统会一页一页地为进程提供内存,但进程不应该在分配另一个内存之前耗尽该页面吗?为什么不呢?实际上操作系统一次给进程多个页面,不知道这些页面是根据什么算法给的。当进程决定分配一个小对象(比如你的)时,它将从一个可用的页面中进行选择,并将其存储到该页面中,同时还会产生一些开销。在分配的特定时间,进程可能会决定需要更多的页面,并要求操作系统增加内存,然后这将失败。做一个快速的实验,在指针之间做算术上的区别。你会注意到它们之间并没有16个字节的间隔。但是为什么进程在要求更多的空间之前不先使用它提供的空间,以至于程序占用了它应该占用的近两倍的空间呢?