【问题标题】:malloc() not allocate memory for large blocks of memorymalloc() 不为大块内存分配内存
【发布时间】:2016-02-13 15:45:33
【问题描述】:

我正在尝试制作一个分配内存的程序,然后用随机数据填充分配的内存,在本例中为A,并多次执行此操作,然后以毫秒为单位打印填充 100 mb 所需的时间. 该程序应该每次分配 100 mb 的倍数。该程序应该做到这一点高达 9000 mb。我这样做的原因是为了演示操作系统在耗尽可用内存并使用交换空间时的行为。但是我在这样做时遇到了问题。

当我运行程序时,它的行为就像它应该做的那样,直到我达到 2100 mb 然后它停止分配内存,一段时间后错误处理程序启动并退出程序,因为 malloc() 返回 NULL。

这是代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <assert.h>
#include <unistd.h>
#define KILO    1024
#define MEGA (KILO*KILO)
#define INCREMENT 100

int diffTime(struct timeval * startTime, struct timeval * endTime) {
    return ((endTime->tv_sec - startTime->tv_sec)*1000 + (endTime->tv_usec- startTime->tv_usec)/1000);
}

int createBigDatablock(long int storlek) {
    char *arr = (char*) malloc(storlek*MEGA);
    if (arr==NULL){
        printf("Error: not allocating memory");
        exit (-1);  
    }
    for(int i = 0;i<storlek*MEGA;i++){
        arr[i] = 'A';
    }
    fflush(stdin);
    getchar();
    free(arr);
    return 0;
}



int main(void) {
    long int i;
    struct timeval startT, endT;
    // struct timezone tzp;
    for(i=INCREMENT;i<=9000;i=i+INCREMENT){
        gettimeofday(&startT, NULL); //&tzp); /* hämta starttid */
        createBigDatablock(i);
        gettimeofday(&endT, NULL);//&tzp); /* hämta sluttid */
        printf("Datablock  %ld MB took %d msec\n",i, diffTime(&startT,&endT));
    }
    return 0;
}

我尝试在具有 4 GB 内存和 570 mb 交换空间的 debian 8 虚拟机上运行它。内存永远不会被完全填满,交换空间也永远不会被触及。如果有人能帮我解决这个问题,我会很感激的

【问题讨论】:

  • 要么你在 32 位机器上,然后你运气不好,要么你的系统有一个进程可以使用多少内存的资源限制。使用ulimit -mulimit -vulimit -d 进行检查。

标签: c memory debian


【解决方案1】:

我偶然发现了这段代码,并在 Fedora 34 X86_64 系统上编译了它。它会在将 A 写入内存位置的循环上的数据块 2100 处出现段错误。我将 i 更改为 long int i 并且我的系统几乎停止运行,但在另一个终端中看到的空闲显示它正在填充交换。我还没有完全测试它,但它似乎正在工作。这里有两个 i 变量,也许它们被认为是独立的。

for(int i = 0;i<storlek*MEGA;i++){
    arr[i] = 'A';


for(long int i = 0;i<storlek*MEGA;i++){
    arr[i] = 'A';

【讨论】:

    【解决方案2】:

    您可能有一个 32 位系统,您不能为每个进程分配超过 2 GB 的内存。

    如果malloc返回NULL,则表示无法分配内存。

    所以你的程序的行为是正常的。

    另一种可能性是它根本找不到足够大的空闲连续内存块。

    从未触及交换空间的原因可能是因为您的虚拟机有 4gb 的内存,所以总是有足够的可用内存。 如果您想使用交换空间,您可以尝试分配大量较小的内存块,例如 40 乘以 100Mb;那么你可以分配的内存总量也可能高于2100Mb。

    【讨论】:

    • OP 说他在 Debian,但不排除他正在为 i386 编译。
    • 另外,32 位进程的地址空间限制是 4 GiB,而不是 2 GiB。
    • @FUZxxl,地址空间是的,但可分配的内存可能会更少(就像在 32 位 Windows 上一样)
    • @MichaelWalz 谢谢你的回答,你说的很有道理!我现在尝试在 64 位 Debian 上运行代码,现在它似乎工作得更好了!但是,我现在在使用 2100Mb 块时遇到了分段错误。 malloc() 在尝试分配 2100Mb 时不返回 NULL,但是当恰好 2048Mb 写入数组时,我遇到了分段错误。任何想法为什么?我知道我已经接受了您的回答,但我非常感谢您的帮助!谢谢!
    • @JuliaRundström 也许这是一个“关闭一个”错误。否则,您应该发布一个新问题并提供一个展示此行为的最小示例。
    猜你喜欢
    • 1970-01-01
    • 2013-07-04
    • 2012-12-26
    • 1970-01-01
    • 1970-01-01
    • 2013-02-23
    • 2014-07-17
    • 2021-03-09
    • 1970-01-01
    相关资源
    最近更新 更多