我想做什么: 回答:我正在尝试在基于 Linux 2.6.31 的无交换嵌入式设备上创建内存碎片。
原因: 答:我正在尝试将一些补丁移植到 Linux 2.6.31 以对碎片化的内存进行碎片整理。为了测试这些补丁是否正常工作,我想先尝试对内存进行碎片化。
我了解到应用持续分配和释放内存会导致碎片化。因此我编写了这些简单的 C 程序。
#include <stdio.h>
#include <stdlib.h>
int main(void) {
srand(time(NULL));
int i = 0, j = 0, randnum=0;
while(1) {
randnum = rand()%10000000;
double *ptr = (double*) malloc(sizeof(*ptr) * randnum);
for(j = 0 ; j < randnum; j++) {
*(ptr+j) = (double)j+1;
}
free(ptr);
}
}
==========
#include <stdio.h>
#include <stdlib.h>
int main(void) {
srand(time(NULL));
int i = 0, j = 0, randnum=0;
int arr[6] = { 3072, 7168, 15360 , 31744, 64512, 130048};
while(1) {
for (i = 0; i < 6 ; i++) {
int *ptr = (int*) malloc(arr[i] * 93);
for(j = 0 ; j < arr[i] * 93 / sizeof(int); j++) {
*(ptr+j) = j+1;
}
free(ptr);
}
}
}
如何衡量内存是否碎片化?:
答:我看/proc/buddyinfo
我需要什么:? 你能建议一种更好的内存碎片方法吗?因为那些 C 程序运行起来非常非常慢。
最佳答案
您将无法通过您正在使用的方法在伙伴分配器的意义上造成明显的碎片。
原因是伙伴分配器使用物理内存。用户空间 malloc
使用逻辑内存 并在底层(通过 sbrk
或 mmap(... MAP_ANON)
) 将调用get_free_page
来分配单页。因此它不需要物理内存相邻,即物理页面可以位于完全不同的内存地址,但 MMU 将使它们一起出现。此外,用户空间不使用 GFP_ATOMIC
(或者现在可能称为 GFP_NOWAIT
)进行分配,因此它可以简单地交换内容以使其工作。
您需要做的是找到可以一次为 GFP_ATOMIC
分配超过 4k 的内核内存的东西。发送和接收大型网络数据包是在用户空间中执行此操作的一种方式(即使是这些片段,我认为片段重组需要一个连续的缓冲区)。更好的方法是放入一个简单的仅用于测试目的的 ioctl 来分配和释放内核 block (如果还没有的话)。
历史记录:虽然看起来很奇怪,但最初的 linux 好友内存分配器是我的第一个 C 程序(在他接受之前被 Linus 重写),尽管上次我查看我当时的电子邮件地址仍然在某个地方在 kmalloc.c
中。我不推荐将此作为学习 C 的方法。
关于c - 如何在基于 Linux 的嵌入式设备上造成内存碎片?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22236225/