多次调用malloc-高于预期的内存使用率
当我在windows下运行以下32位应用程序(调试模式)时,内存使用量达到2GB限制,当我等于42885988时,循环中断:多次调用malloc-高于预期的内存使用率,c,memory-management,C,Memory Management,当我在windows下运行以下32位应用程序(调试模式)时,内存使用量达到2GB限制,当我等于42885988时,循环中断: for(int i = 0; i < 104857600; ++i) { uint8_t* ptr = (uint8_t*)malloc(1); if (!ptr) { break; } *ptr = 0; } for(int i=0;i
for(int i = 0; i < 104857600; ++i)
{
uint8_t* ptr = (uint8_t*)malloc(1);
if (!ptr)
{
break;
}
*ptr = 0;
}
for(int i=0;i<104857600;++i)
{
uint8_t*ptr=(uint8_t*)malloc(1);
如果(!ptr)
{
打破
}
*ptr=0;
}
104857600即100mb,那么如何解释上述程序的行为呢?malloc(1)
不分配一个字节
malloc
手册页指出,返回的内存“对于任何内置类型都是适当对齐的”。因此,如果对malloc
的第一次调用返回地址0x1000,第二次调用可能无法返回0x1001,因为该地址可能“对于任何内置类型都不是适当对齐的”(一些处理器无法访问奇数地址的字,或者通常无法访问不可被N整除的地址的N字节值,以及一些效率较低的地址的N字节值。)因此,第二个malloc
调用必须返回至少0x1004或甚至0x1008
另外,malloc
必须分配额外的内存来存储它返回给您的缓冲区的信息。当您稍后调用free
时,该函数必须知道缓冲区的大小,例如,在64位机器上至少还有8个字节。根据运行时管理堆的方式,它可能必须存储额外的内存信息
如果您假设每个malloc
实际分配了至少8个字节(用于对齐)加上另外8或16个字节用于内务管理,您可以看到1亿次调用malloc
,每个调用一个字节可以使您的容量超过2GB
我不确定您的每个呼叫是否实际使用了16或24字节或其他内容;关键是它远远不止一个。2GB/42885988是每个分配超过50字节的阴影
这比简单的Windows堆分配所期望的要多,因此我怀疑您正在运行调试版本,在这种情况下,分配的内存周围会有额外的保护字节开销。更多详细信息请参阅本文-。跟踪内存块不是免费的。每个分配将使用多个字节。@Ry-你能详细解释一下吗?我不知道Windows的详细信息。看起来像是“低碎片堆”是一件事。但至少,你有8字节对齐。你知道分配一个字节的内存实际上毫无意义。@Ryker不要误解我,这个问题没关系。我只是想确保OP理解这一点。是的。我在调试模式下运行应用程序。