次の C コードの例 ( http://bugs.python.org/issue19246から取得) は、32 ビット モードでコンパイルされている間に、Windows 7 64 ビットで実行されます。
#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 MB のチャンクがありません。ただし、ストレス手順は、メモリエラーなしで継続的に繰り返すことができます。
質問は次のとおりです。
- 完全に使用されていない場合、メモリをどのように断片化できますか?
- そのプロセスのメモリの断片化をどのように修正できますか?