действительно освобождает всегда (портативно) освобождает, и зарезервируйте память для процесса или возвратов к ОС

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

 /* 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 вызовы не перестали бы работать?

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

6
задан Aditya Sehgal 21 June 2010 в 18:39
поделиться

10 ответов

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

7
ответ дан 8 December 2019 в 02:40
поделиться

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

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

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

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

5
ответ дан 8 December 2019 в 02:40
поделиться

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

4
ответ дан 8 December 2019 в 02:40
поделиться

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

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

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

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

4
ответ дан 8 December 2019 в 02:40
поделиться
  1. Нет, вы не можете сделать это с уверенностью. Он переносимый только в том смысле, что он действителен на C и, вероятно, будет компилировать где бы вы ни попробовали, но все же неверно полагаться на это предполагаемое (и недокументированное) поведение.

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

4
ответ дан 8 December 2019 в 02:40
поделиться

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

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

3
ответ дан 8 December 2019 в 02:40
поделиться

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

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

3
ответ дан 8 December 2019 в 02:40
поделиться

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

0
ответ дан 8 December 2019 в 02:40
поделиться

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

3
ответ дан 8 December 2019 в 02:40
поделиться

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

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

1
ответ дан 8 December 2019 в 02:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: