Я пытаюсь найти максимальный объем памяти, который я мог бы выделить в стеке, глобальной памяти и куче памяти в C ++. Я пробую эту программу в системе Linux с 32 ГБ памяти и на моем Mac с 2 ГБ ОЗУ.
/* test to determine the maximum memory that could be allocated for static, heap and stack memory */
#include <iostream>
using namespace std;
//static/global
long double a[200000000];
int main()
{
//stack
long double b[999999999];
//heap
long double *c = new long double[3999999999];
cout << "Sizeof(long double) = " << sizeof(long double) << " bytes\n";
cout << "Allocated Global (Static) size of a = " << (double)((sizeof(a))/(double)(1024*1024*1024)) << " Gbytes \n";
cout << "Allocated Stack size of b = " << (double)((sizeof(b))/(double)(1024*1024*1024)) << " Gbytes \n";
cout << "Allocated Heap Size of c = " << (double)((3999999999 * sizeof(long double))/(double)(1024*1024*1024)) << " Gbytes \n";
delete[] c;
return 0;
}
Результаты (на обоих):
Sizeof(long double) = 16 bytes
Allocated Global (Static) size of a = 2.98023 Gbytes
Allocated Stack size of b = 14.9012 Gbytes
Allocated Heap Size of c = 59.6046 Gbytes
Я использую GCC 4.2.1. Мой вопрос:
Почему моя программа работает? Я ожидал, так как стек исчерпал себя (16 МБ в Linux и 8 МБ в Mac), программа должна выдать ошибку. Я видел некоторые из множества вопросов, заданных в этой теме, но я не мог решить свою проблему из ответов, данных там.
В некоторых системах вы можете выделить любой объем памяти, который умещается в адресном пространстве. Проблемы начинаются, когда вы фактически начинаете использовать эту память.
Что происходит, так это то, что ОС резервирует виртуальный диапазон адресов для процесса, не привязывая его к чему-либо физическому или даже проверяя, достаточно ли физической памяти (в том числе подкачки) для резервирования этого диапазона адресов. Отображение происходит только постраничным способом, когда процесс пытается получить доступ к вновь выделенным страницам. Это называется чрезмерная память.
Попробуйте получить доступ к каждому sysconf(_SC_PAGESIZE)
байт ваших огромных массивов и посмотрим, что получится.
Linux перегружает, что означает, что он может позволить процессу больше памяти, чем доступно в системе, но только когда эта память фактически используется процессом, фактическая память (физическая основная память или пространство подкачки на диске) выделяется для процесса , Я думаю, что Mac OS X работает аналогичным образом.