【发布时间】:2011-11-08 01:44:02
【问题描述】:
我正在编写一个测试动态内存分配的程序,以了解 50% 规则的适用程度。
该程序有 10,000 个指向动态分配的内存块的指针。它还有一个数组来存储每个块的大小。它应该:
- 使用
malloc()为ptrList的每个元素动态分配一块内存。这些块的大小应在 1 到 10,000 字节范围内随机选择,并且块大小应存储在sizeList数组中。 - 初始块分配后,程序应反复释放块并分配新块。这应该循环 100,000 次迭代。在每次迭代中,随机选择
ptrList中的索引,释放该块,然后替换为具有随机大小的新动态分配块。 - 每 100 次迭代后,它应该打印出一行,显示迭代计数、近似堆大小(由任何块中包含的最高和最低内存地址之间的差异确定)以及所有块的总大小
ptrList指向的块。
我的程序编码如下:
#include <stdio.h>
#include <pthread.h> /* for pthreads */
#include <stdlib.h> /* for exit */
/** Number of memory blocks to allocate/deallocate. */
#define BLOCK_COUNT 10000
/** Number of free/malloc operations to perform */
#define TEST_LENGTH 100000
/** Maximum size of an allocated block. */
#define SIZE_LIMIT 10000
int main( int argc, char *argv[] ) {
// Array of pointers to all blocks that have been allocated.
char *ptrList[ BLOCK_COUNT ];
// Array of sizes for each block, so we can know how much memory we're using.
int sizeList[ BLOCK_COUNT ];
// Insert your code here
for (int j = 0; j < 1000; j++) {
int minimum = 0;
int maximum = 0;
int total = 0, remainder = 0;
for (int i = 0; i < BLOCK_COUNT; i++) {
int size = (rand() % SIZE_LIMIT) + 1;
ptrList[i] = malloc (size);
sizeList[i] = size;
total += size;
int heapsize = (int)ptrList[i];
if (i == 0) {
maximum = heapsize;
minimum = heapsize;
}
else {
if (heapsize > maximum) {
maximum = heapsize;
}
if (heapsize < minimum) {
minimum = heapsize;
}
}
}
for (int i = 0; i < TEST_LENGTH; i++) {
int index = rand() % BLOCK_COUNT;
int size = (rand() % SIZE_LIMIT) + 1;
free(ptrList[index]);
total -= sizeList[index];
ptrList[index] = malloc (size);
sizeList[index] = size;
total += sizeList[index];
int heapsize = (int)ptrList[index];
if (heapsize > maximum) {
maximum = heapsize;
}
if (heapsize < minimum) {
minimum = heapsize;
}
}
if (j > 0) {
remainder = j % 100;
}
if (remainder == 0 ) {
//printf("%d", example);
printf("%d %d %d\n", j, maximum - minimum, total);
}
for (int i = 0; i < BLOCK_COUNT; i++) {
free(ptrList[i]);
}
}
return 0;
}
我是否以正确的方式处理内存的分配/解除分配?在我用int j 实现for 循环之前,我的程序编译并运行(没有输出)。在我实施后它挂起,所以也许有人可以帮我解决问题。
编辑: 50% 规则是所有块的总大小除以堆大小的近似值,通常约为 50%。
【问题讨论】:
-
“我实现它后它挂起” - 这通常被认为是一个问题......
-
@MitchWheat 是的,我不太确定是什么原因造成的。注释掉
for (int j = 0; j < 1000; j++)允许程序运行完成。一旦我重新评论该行,程序就会挂起。我也尝试在每次迭代结束时添加一个for循环来释放内存。 -
仅供参考,随机分配和释放一直是程序内存使用的非常糟糕的模型。您可以从这样的实验中得出的可靠结论并不多。通过将分配器替换为几个大进程,您可能会获得更有趣的数据——例如 Web 浏览器(连续运行)或编译器(在处理文件后结束)。
-
它挂起,还是需要很长时间?您应该让它打印进度消息。您应该检查 malloc 的结果是否为 null。
-
我也很好奇您所说的“50% 规则”是什么意思。如果您的意思是 50% 的堆内存在名义上已满时会被占用,那将证明堆管理器相当糟糕。