2010-02-01 5 views
5

Je vois un comportement totalement différent lors de l'exécution d'un programme qui essaie de dépasser RSS sur des machines différentes. Le code est quelque chose comme:malloc se comporte différemment sur différentes machines

... 
    char** s = (char**)malloc(10000*sizeof(char*)); 

    for (i = 0; i < 10000; i++){ 
    s[i] = (char*)malloc(1000*1000*sizeof(char)); 
    if (s[i] == NULL) { 
     printf("cannot allocate memory for s[%d]",i); 
     exit(1); 
    } 
    } 

    int j = 0; 
    while(1){ 
    for (i = 0; i < 10000; i++){ 
     for (j = 0; j < 1000*1000; j++) { 
     s[i][j] = 1; 
     } 
     if ((i % 100) == 0) printf("i = %d\n", i); 
    } 
    } 
    for (i = 0; i < 10000; i++) 
    free(s[i]); 
    free(s); 
... 

Le code ci-dessus tente d'allouer environ 10 Go de mémoire en utilisant malloc. Les deux premières machines, j'ai essayé ce code sur Linux 2.6 et le dernier tourne sur Linux 2.4. Voici les comportements que je vois sur ces machines:

Machine1: la mémoire est allouée en utilisant la mémoire overcommit, mais lors de l'affectation de valeurs aux emplacements de mémoire dans la boucle while, elle alloue seulement autant que le permet le RSS. Ainsi, OOM Killer tue le processus quand i = 3800 est imprimé, ce qui représente environ 4 Go de mémoire.

Machine2: la mémoire est allouée en utilisant la mémoire overcommit et la boucle while s'allume indéfiniment, allouant des pages à partir de la mémoire virtuelle. Le processus devient un peu plus lent après l'impression de i = 3800, ce qui est normal.

machine3: cette machine ne dispose que de 2 Go de mémoire. La mémoire ne peut même pas être allouée. On dirait que l'over-commit n'est pas défini ou que le noyau 2.4 ne supporte pas l'allocation de pages de machines virtuelles en utilisant malloc! Ainsi, dans la première boucle for, il se ferme lors de l'allocation de la mémoire pour i = 2138

Mon action souhaitée est celle qui se passe dans la machine2. Est-ce que quelqu'un sait quelles options (kernel?) Doivent être définies pour permettre au système d'exploitation d'allouer des pages de mémoire virtuelle en utilisant malloc et de lancer la pagination alors que la mémoire requise dépasse RSS?

Merci

+1

Où est 'if (s! = NULL)' de la première allocation? –

+0

Préférence personnelle: Au lieu de 'char ** s = (char **) malloc (10000 * sizeof (char *));' et 's [i] = (char *) malloc (10000 * sizeof (char)); 'Je ferais' char ** s = malloc (10000 * sizeof * s); 'et' s [i] = malloc (10000 * sizeof ** s); '. De cette façon, si 's' passe d'un' char ** 'à un' wchar_t ** 'dans le futur, tous vos appels' malloc' s'adapteront au besoin. En général, la valeur de retour de 'malloc()' n'est pas nécessaire en C, et certains (comme moi) considèrent que c'est une mauvaise idée car cela empêche la maintenabilité. –

+0

Architecture? x86_64? –

Répondre

5

Vous ne serez pas en mesure d'allouer 100 Go sur une machine 32 bits et l'adresse à l'aide des pointeurs réguliers, ce qui est ce que votre code semble utiliser. Le fait que la machine 1 termine le processus lorsqu'elle atteint environ 4 Go et la machine 2 ne suggère pas fortement que la machine 2 exécute un système d'exploitation 64 bits.

+0

J'ai fait une erreur dans mon message original que j'ai édité et corrigé. Si vous regardez le code, il demande seulement 10 Go de mémoire et pas 100 Go. Quoi qu'il en soit, les deux machines 1 et 2 exécutent des systèmes d'exploitation 64 bits. Ces deux sont supposés être identiques puisque leur matériel est exactement le même et configuré de manière identique. – Pirooz

Questions connexes