2013-08-23 4 views
4

Основное применение моего, рушится во время работы.Распределение памяти - как 15 ГБ может быть равным 2 ГБ?

Я хочу узнать, связано ли это с проблемой выделения памяти системой. Таким образом, я создал небольшую тестовую программу для выделения 1 ГБ памяти и одновременно выполнил 15 таких процессов, таким образом, используя в общей сложности 15 ГБ ОЗУ.

Однако, когда я запускаю эту программу, диспетчер задач показывает, что он занял только 2 ГБ ОЗУ? Как это возможно?

Я написал пример кода следующим образом

char *ptr[1024]; 
for (i = 0 ; i < 1024 ; ++i) 
{ 
    ptr[i] = new char[1024 * 1024]; 
    std::cout << " Allocated 1024 MB" << i << " th time " << std::endl; 
} 
+5

Возможно, операционная система overcommits? I. e., 'New' возвращает действительный указатель, хотя памяти недостаточно.Попробуйте * на самом деле * вырвать что-то в полученную память, и ваш процесс, вероятно, будет убит. –

+2

Диспетчер задач не отображает «занятый объем памяти». Он показывает [рабочие наборы] (http://windows.microsoft.com/en-us/windows-vista/what-do-the-task-manager-memory-columns-mean), и это совсем другое. –

ответ

8

Попробуйте хранить данные в ваших больших массивов. У Мемсета все будет хорошо. Возможно, вы, вероятно, смотрите на реальную память, если не трогаете ее, это может быть только в виртуальной памяти.

+0

Спасибо Дэйл. Решила головоломку, используя memset. – user373215

+0

Это бессмысленная вещь, она просто замедляет работу программы. –

+0

@HansPassant: Совсем нет, он вызывает ошибки во всех этих страницах и создает физические страницы. В противном случае эта выделенная память просто укажет на фиктивную нулевую страницу. Поскольку OP хочет заставить систему распределять память, это правильно. – Damon

14

Windows - операционная система с виртуальной памятью с запросами. Выделение памяти оператором new выделяет только виртуальный память. Вы не начнете использовать физическое память, оперативная память, пока не на самом деле доступ память. Которых вы не делали.

Вы можете заставить RAM выделяться прикосновением каждый 4096th байт, лучше сделать это в записи или она будет оптимизирована прочь:

size_t size = 1024 * 1024; 
    ptr[i] = new char[size]; 
    for (size_t j = 0; j < size; j += 4096) ptr[i][j] = 0; 

Но это совершенно бессмысленно, что нужно сделать, это просто замедляет программа вниз. И на самом деле ничего не тестирует, процесс не может закончиться из ОЗУ в Windows. Поместите диспетчер задач в режим программиста, добавьте столбец для размера Commit. Это реальное число.

+0

Обратите внимание, что при необходимости оно обеспечивает доступность пространства. В отличие от некоторых операционных систем, которые лежат, а затем должны начать убивать людей, чтобы удовлетворить потребности в памяти. –

+0

@ Hans Passant: Я бы хотел, чтобы у вас была ссылка на технический фон. –

+0

Я считаю, что отложенное распределение - это просто глупо. –

1

Может быть, ОС overcommits, i. e., operator new возвращает действительный (не NULL) указатель, хотя памяти недостаточно. Попробуйте на самом деле написать что-то в память, и ваш процесс, вероятно, будет убит (или, по крайней мере, использование физической памяти увеличивается).

0

http://en.wikipedia.org/wiki/Virtual_memory

Вы существенно наполняя файл подкачки с данными. ОС видит, что вы выделяете много данных, но пока вы его не используете, эти данные не будут извлекаться из файла страницы в основную память.

1

ОС (будь то Windows, Linux или MacOS) не ожидает, что все процессы, которые выделяют память, фактически используют всю эту память. Многие программы делают такие вещи, как выделение 1 МБ для хранения файла, а затем заполняют его 14 Кбайт файловых данных (потому что это проще, чем выяснять, насколько большой файл и на самом деле выделить нужную сумму). Таким образом, вместо того, чтобы выполнять все усилия по созданию реальной физической памяти, доступной для памяти, которая не может быть использована, она просто оставляет ее в виртуальном пространстве, а затем находит некоторую физическую память, когда память фактически используется.

Таким образом, объем памяти, отображаемый в диспетчере задач, - это только фактическая память, которую вы используете, а не память, которую вы выделили, но не использовали.

Если вы пишете цикл, который записывает каждый 256-й или 1024-й байт в своем распределении, он должен «расти» и показывать фактическое количество выделенной памяти.