освобождает всегда (переносимо) освобождает и резервирует память для процесса или возвращает к ОС - PullRequest
6 голосов
/ 21 июня 2010

Я прочитал, что free () "вообще" не возвращает память в ОС. Можем ли мы свободно использовать эту функцию free (). Например, это портативный?

 /* Assume I know i would need memory equivalent to 10000 integers at max
    during the lifetime of the process */

 unsigned int* p = malloc(sizeof(unsigned int) * 10000);

 if ( p == NULL)
  return 1;

 free(p);

 /* Different points in the program */

 unsigned int* q = malloc(sizeof(unsigned int) * 5);

 /* No need to check for the return value of malloc */

Я пишу демо, где я бы заранее знал, сколько call contexts поддержит.

Можно ли заранее выделить "n" количество "call contexts" structures, а затем немедленно free. Это гарантировало бы, что мои будущие malloc звонки не потерпят неудачу?

Это дает мне какое-либо преимущество в отношении эффективности? Я думаю, что еще одна проверка «если» плюс, будет лучше работать с памятью, если большой кусок был изначально получен и теперь доступен бесплатно. Будет ли это вызвать меньше фрагментации?

Ответы [ 10 ]

7 голосов
/ 21 июня 2010

Было бы лучше оставить начальный блок памяти выделенным, чем использовать пул, чтобы сделать его доступным для клиентов в вашем приложении. Не стоит полагаться на эзотерические поведения, чтобы поддерживать стабильность вашего кода. Если что-нибудь изменится, вы можете иметь дело с плохими указателями и сбоями программы.

5 голосов
/ 21 июня 2010

Вы запрашиваете портативный и низкоуровневый способ управления тем, что происходит на стороне интерфейса памяти .

В любой ОС (потому что c - один из наиболее распространенных языков).

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

Существует причина, по которой обычные c API-интерфейсы определяют только то, как все должно выглядеть и вести себя со стороны c интерфейса, а не как вещи должны быть на стороне ОС.

4 голосов
/ 21 июня 2010

Хм, нет.Внутреннее malloc(3) вызывает brk(2), чтобы расширить сегмент данных, если он слишком мал для данного запроса на выделение.Он касается некоторых страниц для своей внутренней бухгалтерии, но, как правило, в этот момент не все выделенные страницы могут быть защищены физической памятью.

Это происходит потому, что многие ОС делают переполнение памяти - обещание приложению того, что оно запрашивало, независимо от доступной физической памяти, в надежде на то, что приложение будет использовать не всю память, что другие приложения освобождают память / завершают работу, и возвращаются к обмену в качестве крайней меры.Скажем, в Linux malloc(3) почти никогда не происходит сбоев.

Когда на память действительно ссылаются, ядру нужно будет найти доступные физические страницы для ее резервного копирования, создать / обновить таблицы страниц и TLB и т. Д. - нормальная обработка дляошибка страницы.Итак, еще раз, нет, вы не получите никакого ускорения позже, если не зайдете и не дотронетесь до каждой страницы в этом выделенном чанке.

Отказ от ответственности: вышеупомянутое не может быть точным для Windows (поэтому, нет, опять же, ничего близкопортативный.)

4 голосов
/ 21 июня 2010

Вы не можете переносимо полагаться на такое поведение malloc().Вы можете полагаться только на malloc(), который дает вам указатель на память блока заданного размера, которую вы можете использовать, пока не вызовете free().

4 голосов
/ 21 июня 2010
  1. Нет, вы не можете надежно сделать такую ​​вещь.Это portable только в том смысле, что это допустимый C и, вероятно, скомпилирует везде, где вы попробуете, но все еще неправильно полагаться на это предполагаемое (и недокументированное) поведение.*

  2. Вы также не получите заметно более высокую производительность.Простая проверка на NULL возврат от malloc() - это не то, что замедляет вашу программу.Если вы считаете, что все ваши вызовы malloc() и free() замедляют вашу программу, напишите свою собственную систему распределения с нужным вам поведением.

3 голосов
/ 21 июня 2010

malloc (3) также выполняет mmap (2), следовательно, free (3) делает munmap (2), следовательно, вторая malloc () может в теории потерпеть неудачу.

3 голосов
/ 21 июня 2010

Совсем нет. Это совсем не портативно. Кроме того, нет никакой гарантии, что другой процесс не использовал бы используемую память - C работает на многих устройствах, таких как встроенные, где адресация виртуальной памяти не существует. И при этом это не уменьшит фрагментацию - вам нужно знать размер страницы машины и выделять точное количество страниц - и затем, когда вы их освободите, они снова будут просто не фрагментированы.

Если вы действительно хотите гарантировать неправильную память, malloc большой блок и вручную помещать в него объекты. Это единственный способ. Что касается эффективности, вы должны работать на невероятно голодном устройстве, чтобы сэкономить несколько ifs.

3 голосов
/ 21 июня 2010

Нет, нет гарантии, что free () не освободит память назад, и нет гарантии, что ваш второй malloc будет успешным.

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

1 голос
/ 21 июня 2010

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

Итак, если вы хотите, чтобы это было гарантировано, вам в значительной степени нужно написать свой собственный распределитель. Типичной стратегией является выделение большого блока из malloc (или чего-либо еще) и перераспределение фрагментов для остальной части программы для использования из этого большого блока (или, возможно, нескольких больших блоков).

0 голосов
/ 21 июня 2010

Для лучшего контроля вы должны создать свой собственный распределитель памяти. Примером распределителя памяти является этот . Это единственный способ получить предсказуемые результаты. Все остальное, что зависит от неясных / недокументированных функций и работ, можно отнести к удаче.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...