В linux malloc
ведет себя оппортунистически, только резервное копирование виртуальной памяти по реальной памяти при первом доступе. Можно ли было бы изменить calloc
так, чтобы он также вел себя так (выделение и обнуление страниц при первом доступе)?Сделать calloc оппортунистическим
ответ
Это не функция malloc()
, которая делает ее «оппортунистической». Это особенность ядра, с которым malloc()
не имеет ничего общего.
malloc()
запрашивает ядро для пощечины памяти каждый раз, когда ему требуется больше памяти для выполнения запроса, и это ядро, которое говорит «Да, конечно, у вас есть» каждый раз, без фактического обеспечения памяти. Это также ядро, которое обрабатывает последующие ошибки страницы, поставляя нулевые страницы памяти. Обратите внимание, что любая память, которую ядро поставляет, будет уже обнулена из-за соображений безопасности, поэтому она одинаково хорошо подходит для malloc()
и для calloc()
.
То есть, если реализация calloc()
портит это, безоговорочно обнуляя сами страницы (создавая ошибки страницы, которые побуждают ядро фактически поставлять память), он будет иметь такое же «оппортунистическое» поведение, как malloc()
.
Обновление:
В моей системе, следующая программа успешно выделяет 1 TiB в системе только 2 ГиБ памяти (!):
#include <stdlib.h>
#include <stdio.h>
int main() {
size_t allocationCount = 1024, successfullAllocations = 0;
char* allocations[allocationCount];
for(int i = allocationCount; i--;) {
if((allocations[i] = calloc(1, 1024*1024*1024))) successfullAllocations++;
}
if(successfullAllocations == allocationCount) {
printf("all %zd allocations were successfull\n", successfullAllocations);
} else {
printf("there were %zd failed allocations\n", allocationCount - successfullAllocations);
}
}
Я думаю, его с уверенностью сказать, что по крайней мере, реализация calloc()
на моем ящике ведет себя «оппортунистически».
«любая память, которую ядро поставляет, будет уже нулевым».Это прекрасно и денди, но как насчет памяти, которая возвращается в кучу «free», а затем «calloc'ed снова? –
Спасибо, я не знал, что ядро обычно нули всю память. Это не объясняет, что я принял приложение (которое я не написал) и изменил вызовы на 'calloc' на' malloc', и он разбился. Я предполагаю, что это связано с тем, что выделенная память не была обнулена, а приложение предполагало, что это будет. –
@ н.м. Любая память, которая не была возвращена ядру, должна быть нулевана 'calloc()', если она будет использоваться для нового выделения. Однако, если реализация 'free()' возвращает память в ядро (через 'munmap()' или 'sbrk()'), новое сопоставление, созданное с помощью 'mmap()' или 'sbrk()', снова будет равным нулю из ядра. – cmaster
Из соответствующего раздела /proc/sys/vm/overcommit_memory
в proc
:
объем памяти в настоящее время выделяется на систему. Собранная память представляет собой сумму всей памяти, которая была распределена процессами, даже если она еще не была «использована» ими. Процесс, который выделяет 1 ГБ памяти (используя malloc (3) или аналогичный), но касается только 300 МБ этой памяти, будет отображаться только с использованием 300 МБ памяти, даже если у него есть адресное пространство, выделенное для всего 1 ГБ. Это 1 ГБ - это память, которая была «зафиксирована» виртуальной машиной и может быть использована в любое время приложением распределения. При включенном строгом перекомпоновке в системе (режим 2/proc/sys/vm/overcommit_memory) распределения, превышающие CommitLimit (подробно описанные выше), не будут разрешены. Это полезно, если нужно гарантировать, что процессы не сбой из-за нехватки памяти, как только память будет успешно распределена.
Хотя явно не сказал, я думаю похож здесь означает calloc
и realloc
. Так calloc
уже ведет себя оппортунистически как malloc
.
'calloc' сильно отличается от' malloc'. 'calloc' гарантирует, что возвращаемая память инициализируется нулем. 'malloc' не делает. Если вы не знаете, что 'calloc' удается обнулить страницы, не касаясь их, или каким-то образом отказывается от обнуления до первого доступа, вы должны подумать дважды, прежде чем делать такие обобщения. –
- 1. Разница между (int *) calloc и просто calloc?
- 2. В чем разница между calloc (10,4) и calloc (1,40)?
- 3. calloc в Swift
- 4. Эквивалентный код для calloc
- 5. calloc() function вместо malloc()
- 6. malloc и calloc
- 7. Calloc(), Structs & C
- 8. Является ли функция calloc calloc вектором указателя? (Язык C)
- 9. Calloc двумерный массив
- 10. предпочитая таНос над calloc
- 11. странная вещь о calloc
- 12. Convert malloc() to calloc()
- 13. calloc() и NULL
- 14. create string with calloc
- 15. Calloc Сбой байт
- 16. Calloc взаимодействует с fgets?
- 17. C11 stdatomic и calloc
- 18. MPI, calloc и бесплатно:
- 19. Strange char **/calloc поведение
- 20. Calloc - выделение памяти
- 21. Два аргумента для calloc
- 22. Malloc или calloc
- 23. Структура calloc c
- 24. MPI calloc вызывает ошибку сегментации
- 25. Установка двойного указателя с calloc
- 26. calloc() заявление синтаксиса с указателями
- 27. Используется ли malloc/realloc/calloc?
- 28. calloc перезаписывает память другой переменной?
- 29. C++ calloc a string array
- 30. Как calloc() 25 байт точно
Обратите внимание, что для больших фрагментов 'calloc' в Linux/glibc уже является оппортунистическим (использует тот же самый вызов MAP_PRIVATE | MAP_ANONYMOUS' mmap, что и новомодные страницы обещают читать как нули). –