2010-02-01 3 views
5

Я вижу совершенно другое поведение при запуске программы, которая пытается превысить RSS на разных машинах. Код выглядит примерно так:malloc ведет себя по-разному на разных машинах

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

Приведенный выше код пытается выделить около 10 ГБ памяти, используя malloc. Первые две машины я пробовал этот код при запуске на linux kernel 2.6, а последний запускал linux kernel 2.4. Вот поведение, которое я вижу на этих машинах:

Machine1: память выделяется с использованием переполнения памяти, но при назначении значений ячейкам памяти в цикле while она выделяет столько, сколько позволяет RSS. Таким образом, OOM Killer убивает процесс, когда i = 3800 печатается, что составляет около 4 ГБ памяти, которую имеет эта машина.

Machine2: память выделяется с использованием переполнения памяти, а цикл while продолжается вечно, выделяя страницы из виртуальной памяти. Процесс становится немного медленнее после печати i = 3800, что является нормальным.

machine3: эти машины имеют всего 2 ГБ памяти. Память даже не может быть выделена. Похоже, что over commit не установлен или ядро ​​2.4 не поддерживает выделение страниц виртуальной машины с помощью malloc! Таким образом, в первом цикле он выходит при распределении памяти для i = 2138

Мое желаемое действие - это то, что происходит в machine2. Кто-нибудь знает, какие параметры (kernel?) Должны быть установлены, чтобы позволить ОС выделять страницы виртуальной памяти с помощью malloc и запускать поисковый вызов, в то время как требуемая память превышает RSS?

Благодаря

+1

Где 'if (s! = NULL)' первого распределения? –

+0

Личные предпочтения: вместо 'char ** s = (char **) malloc (10000 * sizeof (char *));' и 's [i] = (char *) malloc (10000 * sizeof (char)); 'Я бы сделал' char ** s = malloc (10000 * sizeof * s); 'и' s [i] = malloc (10000 * sizeof ** s); '. Таким образом, если '' '' изменяется с 'char **' на 'wchar_t ** 'в будущем, все ваши вызовы' malloc' будут адаптироваться по мере необходимости. В общем случае, отличное значение возвращаемого значения 'malloc()' в C не требуется, и некоторые (как я) считают, что это плохая идея, поскольку она препятствует ремонтопригодности. –

+0

Архитектура? x86_64? –

ответ

5

Вы не сможете выделить 100GB на 32-битной машине и ее решения с помощью регулярных указателей, который является то, что ваш код, кажется, использует. Тот факт, что машина 1 завершает процесс, когда он достигает около 4 ГБ, а машина 2 не дает однозначного подтверждения, что машина 2 работает под 64-разрядной ОС.

+0

Я ошибся в своем оригинальном сообщении, которое я отредактировал и исправил. Если вы посмотрите на код, он запрашивает только 10 ГБ памяти, а не 100 ГБ. Как бы то ни было, обе машины 1 и 2 работают под управлением 64-разрядных ОС. Эти два должны быть идентичными, поскольку их оборудование точно такое же и настроено одинаково. – Pirooz

Смежные вопросы