xem xét mã C sau đây, mà tạo ra 100.000 trang 4KB cỡ, sau đó giải phóng 99.999 trang và, cuối cùng, giải phóng trang cuối cùng:Memory rò rỉ trên phân bổ trang với malloc
#include <stdio.h>
#include <stdlib.h>
#define NUM_PAGES 100000
int main() {
void *pages[NUM_PAGES];
int i;
for(i=0; i<NUM_PAGES; i++) {
pages[i] = malloc(4096);
}
printf("%d pages allocated.\n", NUM_PAGES);
getchar();
for(i=0; i<NUM_PAGES-1; i++) {
free(pages[i]);
}
printf("%d pages freed.\n", NUM_PAGES-1);
getchar();
free(pages[NUM_PAGES-1]);
printf("Last page freed.\n");
getchar();
return 0;
}
Nếu bạn biên dịch nó, chạy nó và theo dõi quá trình sử dụng bộ nhớ, bạn có thể thấy rằng việc sử dụng bộ nhớ đạt khoảng 400MB trước khi getchar
đầu tiên (khi bộ nhớ được cấp cho 100.000 trang), sau đó nó giữ nguyên ngay cả sau khi 99.999 trang được phân bổ (sau giây getchar
) và cuối cùng, nó giảm xuống 1MB khi trang cuối cùng được phân bổ.
Vì vậy, câu hỏi của tôi là tại sao điều này lại xảy ra? Tại sao toàn bộ bộ nhớ chỉ trả về hệ điều hành khi tất cả các trang được giải phóng? Có bất kỳ kích thước trang nào hay bất kỳ sự sắp xếp trang nào ngăn cản điều này xảy ra không? Tôi có nghĩa là, là có bất kỳ kích thước trang hoặc liên kết làm cho bất kỳ trang malloced được hoàn toàn trả lại cho hệ điều hành khi chỉ có một trang được giải thoát?
Điều này xảy ra vì các phân bổ quá nhỏ nên thư viện C của bạn sử dụng 'sbrk()' để tự động thay đổi kích thước dữ liệu chưa được khởi tạo của nó. Nó là tuần tự, do đó, nó chỉ có thể được thu nhỏ khi phân bổ mới nhất được giải phóng. Nếu bạn tăng kích thước phân bổ để nói 131072 byte (128k), 'strace' cho thấy nó sử dụng' mmap() 'thay cho phân bổ, và mỗi' free() 'thực sự trả về phân bổ cho hệ điều hành. Vì vậy, hãy sử dụng bộ nhớ cache cấp phát và chỉ yêu cầu/trả về các khối lớn hơn cho Hệ điều hành. –
@NominalAnimal Man, anh đã cứu mạng tôi! Cảm ơn bạn rất nhiều cho các ý kiến ở trên và dưới đây. Đó là chính xác những gì tôi đã mong đợi từ các câu trả lời. Nếu bạn đã trả lời (không bình luận) điều này, tôi đã chấp nhận câu trả lời của bạn ... – LuisABOL