如何让内核压缩碎片化内存?Fedora 26下C语言内存碎片实验需求
C语言内存碎片实验实现方案(Fedora 26环境)
我来帮你搞定这个算法课的内存碎片实验,结合Fedora 26的环境,给你整理了完整的代码实现、时间测量方法和注意事项:
核心需求拆解
先把作业要求明确下来,避免歧义:
- 首次分配:创建
3*m个数组,每个数组包含800,000个int类型元素(如果需要其他类型,你可以自行修改) - 释放操作:释放所有偶数编号的数组(这里我们约定数组编号从0开始,也就是第0、2、4...个数组)
- 二次分配:创建
m个数组,每个数组包含900,000个int类型元素 - 性能测量:精准记录首次分配整个序列所需的时间
完整代码实现
下面是符合要求的C程序,我已经加了详细注释,方便你理解:
#include <stdio.h> #include <stdlib.h> #include <sys/time.h> // 定义数组元素数量常量 #define FIRST_ARR_SIZE 800000 #define SECOND_ARR_SIZE 900000 int main(int argc, char *argv[]) { // 检查参数,确保传入m的值 if (argc != 2) { fprintf(stderr, "用法: %s <m值>\n", argv[0]); return 1; } int m = atoi(argv[1]); if (m <= 0) { fprintf(stderr, "m必须是正整数\n"); return 1; } int first_total = 3 * m; int second_total = m; // 存储首次分配的数组指针 int **first_arrays = malloc(first_total * sizeof(int *)); if (!first_arrays) { perror("首次分配数组指针失败"); return 1; } // 测量首次分配的时间(用gettimeofday获取高精度时间) struct timeval start, end; gettimeofday(&start, NULL); // 执行首次分配 for (int i = 0; i < first_total; i++) { first_arrays[i] = malloc(FIRST_ARR_SIZE * sizeof(int)); if (!first_arrays[i]) { perror("分配单个数组失败"); // 内存分配失败时,释放已分配的内存 for (int j = 0; j < i; j++) { free(first_arrays[j]); } free(first_arrays); return 1; } // 可选:给数组赋值,避免编译器优化掉空分配(如果需要的话) // first_arrays[i][0] = i; } gettimeofday(&end, NULL); // 计算耗时,单位为毫秒 double elapsed = (end.tv_sec - start.tv_sec) * 1000.0 + (end.tv_usec - start.tv_usec) / 1000.0; printf("首次分配3*%d个数组(每个%d元素)耗时: %.2f 毫秒\n", m, FIRST_ARR_SIZE, elapsed); // 释放偶数编号的数组(编号从0开始) for (int i = 0; i < first_total; i += 2) { free(first_arrays[i]); first_arrays[i] = NULL; // 标记为已释放,避免野指针 } // 执行二次分配 int **second_arrays = malloc(second_total * sizeof(int *)); if (!second_arrays) { perror("二次分配数组指针失败"); // 清理剩余内存 for (int i = 0; i < first_total; i++) { if (first_arrays[i]) free(first_arrays[i]); } free(first_arrays); return 1; } for (int i = 0; i < second_total; i++) { second_arrays[i] = malloc(SECOND_ARR_SIZE * sizeof(int)); if (!second_arrays[i]) { perror("二次分配单个数组失败"); // 清理已分配的二次数组 for (int j = 0; j < i; j++) { free(second_arrays[j]); } free(second_arrays); // 清理首次分配剩余的数组 for (int j = 0; j < first_total; j++) { if (first_arrays[j]) free(first_arrays[j]); } free(first_arrays); return 1; } // 可选:赋值 // second_arrays[i][0] = i; } printf("二次分配%d个数组(每个%d元素)完成\n", m, SECOND_ARR_SIZE); // 清理所有剩余内存 for (int i = 0; i < first_total; i++) { if (first_arrays[i]) free(first_arrays[i]); } free(first_arrays); for (int i = 0; i < second_total; i++) { free(second_arrays[i]); } free(second_arrays); return 0; }
编译与运行方法(Fedora 26)
- 保存代码为
memory_fragmentation.c - 用gcc编译:
gcc -o memory_fragmentation memory_fragmentation.c -Wall
- 运行程序,传入m的值(比如m=10):
./memory_fragmentation 10
注意事项
- 如果你的实验要求元素不是int,只需要修改代码中的
int为对应类型(比如char、long),同时调整sizeof()的参数即可 - 时间测量用了
gettimeofday(),在Linux环境下精度足够;如果需要更高精度,可以改用clock_gettime(CLOCK_MONOTONIC, &ts) - 代码中加入了完整的错误处理和内存清理逻辑,避免内存泄漏
- 如果m值太大导致内存不足,程序会输出错误信息并安全退出
内容的提问来源于stack exchange,提问作者xylafur
相关产品推荐
相关产品推荐

