Following C code example (taken from http://bugs.python.org/issue19246) executed on Windows 7 64-bit, while compiled in 32-bit mode
#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;
}
Outputs:
Successfully allocated 1 MB before stress
Failed to allocate 1 MB after stress
64855 64857 100.003084%
Result may be interpreted as: after whole memory allocation and then freeing it, memory of the process is fragmented so bad, that there is no chunk with length of 1 MB. However, the stress procedure can be repeated continuously without memory errors.
The questions are:
- How memory can be fragmented if it is completely unused?
- How memory fragmentation can be fixed for that process?