2010-02-01 26 views
5

Veo un comportamiento totalmente diferente al ejecutar una parte del programa que intenta exceder el RSS en máquinas diferentes. El código es algo así como:malloc se comporta de manera diferente en diferentes máquinas

... 
    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); 
... 

El código anterior intenta asignar alrededor de 10 GB de memoria con malloc. Las dos primeras máquinas que probé este código se ejecutan en linux kernel 2.6 y la última ejecuta Linux Kernel 2.4. Estos son los comportamientos que veo en estas máquinas:

Máquina1: la memoria se asigna utilizando la sobrecarga de memoria, pero cuando se asignan valores a las ubicaciones de memoria en el ciclo while, solo asigna tanto como RSS permite. Por lo tanto, OOM Killer elimina el proceso cuando se imprime i = 3800, que es alrededor de 4 GB de memoria que tiene esta máquina.

Máquina2: la memoria se asigna utilizando la memoria de compromiso y el ciclo while se activa para siempre, asignando páginas de la memoria virtual. El proceso va un poco más lento después de que se imprime i = 3800, lo que es normal.

máquina3: esta máquina tiene solo 2GB de memoria. La memoria no puede ser asignada. Parece que la sobrecompicación no está establecida o Kernel 2.4 no admite la asignación de páginas de máquinas virtuales utilizando malloc! Por lo tanto, en el primer bucle for sale al asignar memoria para i = 2138

Mi acción deseada es la que ocurre en machine2. ¿Alguien sabe qué opciones (kernel?) Tiene que establecerse para permitir que el sistema operativo aloje páginas de memoria virtual usando malloc y comience la búsqueda mientras la memoria requerida excede el RSS?

Gracias

+1

¿Dónde está 'if (s! = NULL)' de la primera asignación? –

+0

Preferencia personal: en lugar de 'char ** s = (char **) malloc (10000 * sizeof (char *));' y 's [i] = (char *) malloc (10000 * sizeof (char)); 'Haría' char ** s = malloc (10000 * sizeof * s); 'y' s [i] = malloc (10000 * sizeof ** s); '. De esta forma, si 's' cambia de' char ** 'a' wchar_t ** 'en el futuro, todas sus llamadas' malloc' se adaptarán según sea necesario. En general, el lanzamiento del valor de retorno de 'malloc()' no es necesario en C, y algunos (como yo mismo) lo consideran una mala idea ya que dificulta el mantenimiento. –

+0

Arquitectura? x86_64? –

Respuesta

5

usted no será capaz de asignar 100 GB en una máquina de 32 bits y la dirección que el uso de punteros regular, que es lo que su código parece usar. El hecho de que la máquina 1 finaliza el proceso cuando alcanza aproximadamente 4 GB y la máquina 2 no sugiere fuertemente que la máquina 2 esté ejecutando un sistema operativo de 64 bits.

+0

Cometí un error en mi mensaje original que edité y arreglé. Si observa el código, solicita solo 10 GB de memoria y no 100 GB. De todos modos, ambas máquinas 1 y 2 están ejecutando sistemas operativos de 64 bits. Se supone que estos dos son idénticos ya que su hardware es exactamente el mismo y está configurado de manera idéntica. – Pirooz

Cuestiones relacionadas