• [^] # Re: malloc() et realloc() sous linux

    Posté par . En réponse au journal realloc. Évalué à 10.

    À vrai dire, sous linux par défaut, malloc() et realloc() ne retournent finalement jamais NULL. Ce qu'il se passe plutôt, c'est qu'on reçoit toujours un pointeur, et c'est au moment où on se met à l'utiliser qu'il alloue réellement la mémoire.

    Ok, c'est l'overcommit.

    Cependant, même avec l'overcommit totalement désactivé, le noyau linux continuera à renvoyer un pointeur non-NULL, même quand il n'y a plus de mémoire disponible, et OOM-killer sera appelé comme d'habitude quand la mémoire sera accédée.

    C'est faux :

    # cat test.c 
    #include <stdio.h>
    #include <stdlib.h>
    #define BLOCK_SIZE (1024*1024)
    int main(int argc, char *argv[])
    {
     unsigned long size = 0;
     while (malloc(BLOCK_SIZE) != NULL)
     size += BLOCK_SIZE;
     printf("malloc() returned NULL after %uMB\n", (size/(1024*1024)));
     exit(EXIT_SUCCESS);
    }
    
    

    Test :

    # /sbin/sysctl -a | grep overcommit
    vm.overcommit_memory = 0
    vm.overcommit_ratio = 50
    vm.nr_overcommit_hugepages = 0
    # ./test
    malloc() returned NULL after 3057MB
    
    

    Normal, je suis sur 32-bit, plus d'espace d'adressage.

    Maintenant, et activant l'overcommit strict :

    # sysctl vm.overcommit_memory=2
    vm.overcommit_memory = 2
    # sysctl vm.overcommit_ratio=50
    # ./test
    malloc() returned NULL after 626MB
    
    

    En faisant un memset() sur le block retourné par malloc(), dans le premier cas le process se fait tuer par l'OOM killer, dans le deuxième le comportement est le même.