Действительно ли некоторые средства выделения ленивы?

Это предупреждение обычно происходит для пользователей, у которых нет приложения на их устройстве, когда мы пытаемся использовать схему URI iOS, поскольку происходит сбой универсальной ссылки для вашего приложения. Чтобы получить более качественную помощь, не могли бы вы подтвердить правильность настройки универсальной ссылки в приложении iOS с помощью нашего инструмента проверки и сообщить нам свой результат? Кроме того, вы можете найти общие проблемы, которые приводят к сбою универсальных ссылок здесь .

Пожалуйста, обращайтесь по адресу Integration@branch.io, если у вас есть дополнительные вопросы!

10
задан TStamper 14 May 2009 в 16:40
поделиться

6 ответов

В Linux malloc запрашивает память с помощью sbrk () или mmap () - в любом случае ваше адресное пространство расширяется немедленно, но Linux не назначает фактические страницы физической памяти до первой записи в рассматриваемая страница. Вы можете увидеть расширение адресного пространства в столбце VIRT, а фактическое использование физической памяти в RES.

18
ответ дан 3 December 2019 в 15:06
поделиться

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

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

What ' цель этого? По сути, это делает распаковку памяти более или менее постоянной операцией по времени Big O (1) вместо операции Big O (n) (аналогично тому, как планировщик Linux распределяет свою работу вместо того, чтобы выполнять ее одним большим фрагментом).

Чтобы продемонстрировать, что я имею в виду, я провел следующий эксперимент:

rbarnes@rbarnes-desktop:~/test_code$ time ./bigmalloc 

real    0m0.005s
user    0m0.000s
sys 0m0.004s
rbarnes@rbarnes-desktop:~/test_code$ time ./deadbeef 

real    0m0.558s
user    0m0.000s
sys 0m0.492s
rbarnes@rbarnes-desktop:~/test_code$ time ./justwrites 

real    0m0.006s
user    0m0.000s
sys 0m0.008s

Программа bigmalloc выделяет 20 миллионов целых чисел, но ничего с ними не делает. deadbeef записывает по одному int на каждую страницу, в результате получается 19531 запись, а просто записывает 19531 int и обнуляет их. Как видите, deadbeef выполняется примерно в 100 раз дольше, чем bigmalloc, и примерно в 50 раз дольше, чем просто запись.

#include <stdlib.h>    

int main(int argc, char **argv) {

int *big = malloc(sizeof(int)*20000000); // allocate 80 million bytes

return 0;

}

.

#include <stdlib.h>    

int main(int argc, char **argv) {

int *big = malloc(sizeof(int)*20000000); // allocate 80 million bytes

// immediately write to each page to simulate all at once allocation

// assuming 4k page size on 32bit machine

for ( int* end = big + 20000000; big < end; big+=1024 ) *big = 0xDEADBEEF ;    

return 0;

}

.

#include <stdlib.h>

int main(int argc, char **argv) {

int *big = calloc(sizeof(int),19531); // number of writes

return 0;
}
6
ответ дан 3 December 2019 в 15:06
поделиться

Да, память не отображается в ваше пространство памяти, пока вы не дотронетесь до нее. mallocing memory настроит только таблицы подкачки, чтобы они знали, когда вы получаете отказ страницы в выделенной памяти, память должна быть отображена.

3
ответ дан 3 December 2019 в 15:06
поделиться

Используете ли вы оптимизацию компилятора? Может быть, оптимизатор удалил выделение, поскольку вы не используете выделенные ресурсы?

1
ответ дан 3 December 2019 в 15:06
поделиться

Функция называется overcommit - ядро ​​«обещает» вам память, увеличивая размер сегмента данных, но не выделяет ему физическую память. Когда вы касаетесь адреса в этом новом пространстве, процесс вызывает ошибку страницы в ядре, которое затем пытается сопоставить ему физические страницы.

1
ответ дан 3 December 2019 в 15:06
поделиться

Да, обратите внимание на флаги VirtualAlloc ,

MEM_RESERVE
MEM_COMMIT

.

Хех, но для Linux или любого POSIX / BSD / SVR # Система vfork () существует уже много лет и обеспечивает аналогичную функциональность.

Функция vfork () отличается от fork () только в том случае, если дочерний процесс может делиться кодом и данными с вызывающий процесс (родительский процесс). Эта значительно ускоряет клонирование рискуя целостностью родительский процесс, если vfork () используется неправильно.

Использование vfork () для любых целей кроме как прелюдии к немедленному вызов функции из exec family или _exit () не рекомендуется.

Функция vfork () может использоваться для создавать новые процессы без полной копирование адресного пространства старого процесс. Если разветвленный процесс просто собираюсь вызвать exec, пространство данных скопировано от родителя к ребенку fork () не используется. Это особенно неэффективен в постраничном среда, создающая vfork () особенно полезно. В зависимости от размер родительского пространства данных, vfork () может дать значительный повышение производительности по сравнению с fork ().

1
ответ дан 3 December 2019 в 15:06
поделиться
Другие вопросы по тегам:

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