Следующий пример кода C (взяты из http://bugs.python.org/issue19246) выполнен на Windows 7 64-битной, в то время как скомпилирован в 32-битном режимеКак полностью неиспользуемая память может быть фрагментирована?
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int create_huge_linked_list(void **last_item) {
int i;
void *prev_item = NULL;
for(i = sizeof(void *); i < 1000000; i++) {
void *new_item = malloc(i);
if(new_item == NULL) {
break;
}
*(void **)new_item = prev_item;
prev_item = new_item;
}
*last_item = prev_item;
return i;
}
void free_linked_list(void *last_item) {
while(last_item != NULL) {
void *prev_item = *(void **)last_item;
free(last_item);
last_item = prev_item;
}
}
int stress_heap() {
void *last_item;
int amount = create_huge_linked_list(&last_item);
free_linked_list(last_item);
return amount;
}
void stress_twice(void) {
int first = stress_heap();
int second = stress_heap();
printf("%i %i %f%%\n", first, second, 100.0 * second/first);
}
void stress_and_alloc_1_mb() {
void *ptr;
ptr = malloc(1000000);
if(ptr != NULL) {
printf("Successfully allocated 1 MB before stress\n");
free(ptr);
stress_heap();
ptr = malloc(1000000);
if(ptr != NULL) {
printf("Successfully allocated 1 MB after stress\n");
free(ptr);
} else {
printf("Failed to allocate 1 MB after stress\n");
}
} else {
printf("Failed to allocate 1 MB before stress\n");
}
}
int main() {
stress_and_alloc_1_mb();
stress_twice();
return 0;
}
Выходы:
Successfully allocated 1 MB before stress
Failed to allocate 1 MB after stress
64855 64857 100.003084%
Результат может быть интерпретирован как: после того, как весь выделение памяти, а затем ее освобождение, память процесса фрагментирована настолько плохо, что нет фрагмента с длиной 1 МБ. Однако процедуру стресса можно повторять непрерывно без ошибок памяти.
Вопросов:
- Как память может быть фрагментирован, если она полностью не используется?
- Как фрагментация памяти может быть исправлена для этого процесса?
Я предполагаю: 1 MB = 1048576, а не 1000000. Хотя это действительно не имеет большого значения здесь. –
@WedaPashi Не обязательно, это зависит от контекста, это может означать и то, и другое. 1 MiB можно использовать для предотвращения путаницы, которая всегда равна 1048576. – orlp
@ nightcracker: Хорошо сэр. Спасибо –