malloc之后free,再申请Big内存失败.

Cline 2012-02-09 11:04:38
1.调用malloc(64K)多次,直到返回NULL;
2.调用malloc(1M),失败;
3.调用free(64K),释放#1分配的内存.
4.loop #2.
5.释放完#1所有内存, malloc(1M)依然失败.

为什么malloc(1M)不能成功?

Win7, VS2008.

调用HeapCompact(), SetProcessWorkingSetSize()也没用。

#include "malloc.h"
#include < ERRNO.H>

int _tmain(int argc, _TCHAR* argv[])
{
const unsigned int MEM_1_K = 1024;
const unsigned int MEM_64_K = 64 * MEM_1_K;
const unsigned int MEM_MAX = 3 * MEM_1_K * MEM_1_K * MEM_1_K;
int memCount = 0;
void** Mem = new void*[MEM_1_K * MEM_1_K];
unsigned int m = 0;
void* p = NULL;
for(; m < MEM_MAX; ++memCount)
{
p = malloc(MEM_64_K);
if(NULL == p)
{
break;
}
m += MEM_64_K;
if(memCount < (MEM_1_K * MEM_1_K))
{
Mem[memCount] = p;
*(char*)p = 'a';
}
}
::printf("%dk was allocated!", m/MEM_1_K);
//::getchar();
int index = 0;
SIZE_T s;
do
{
p = malloc(MEM_1_K * MEM_1_K);
if(!p)
{
if(index >= memCount)
break;
for(int j = 0; j < 16; j++)
{
if((index < memCount) && Mem[index])
{
free(Mem[index]);
Mem[index] = NULL;
index++;
}
else
{
break;
}
}
s = ::HeapCompact(GetProcessHeap(), 0);
BOOL b = SetProcessWorkingSetSize(GetCurrentProcess(), -1, -1);
if(!b)
{
DWORD dw =::GetLastError();
dw = dw;
}
}
}while(!p);

if(!p)
{
p = ::VirtualAlloc(NULL, MEM_1_K * MEM_1_K, MEM_COMMIT | MEM_RESERVE|MEM_LARGE_PAGES, PAGE_READWRITE);
if(!p)
{
DWORD dw = ::GetLastError();
::printf("Failed to allocate 1M memory!");
::getchar();
}
}
return 0;
}
...全文
161 7 打赏 收藏 举报
写回复
7 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
Cline 2012-02-09
好像是呀。 难道只能写自己的memory management?
  • 打赏
  • 举报
回复
oyljerry 2012-02-09
估计内存产生碎片,或者系统还没有清理出空间来
  • 打赏
  • 举报
回复
ouyh12345 2012-02-09
都成碎片了,找不到1m大小的连续内存
  • 打赏
  • 举报
回复
ouyh12345 2012-02-09
没有连续的内存块?
  • 打赏
  • 举报
回复
Cline 2012-02-09
[Quote=引用 1 楼 chinatcp 的回复:]
用 new delete 试试
[/Quote]

还是不行:
int _tmain(int argc, _TCHAR* argv[])
{
const unsigned int MEM_1_K = 1024;
const unsigned int MEM_64_K = 64 * MEM_1_K;
const unsigned int MEM_MAX = 3 * MEM_1_K * MEM_1_K * MEM_1_K;
int memCount = 0;
void** Mem = new void*[MEM_1_K * MEM_1_K];
unsigned int m = 0;
void* p = NULL;
for(; m < MEM_MAX; ++memCount)
{
try
{
p = new char[MEM_64_K];
}
catch(...)
{
p = NULL;
}
if(NULL == p)
{
break;
}
m += MEM_64_K;
if(memCount < (MEM_1_K * MEM_1_K))
{
Mem[memCount] = p;
*(char*)p = 'a';
}
}
::printf("%dk was allocated!", m/MEM_1_K);
//::getchar();
int index = 0;
SIZE_T s;
do
{
try
{
p = new char[MEM_1_K * MEM_1_K];
}
catch(...)
{
p = NULL;
}
if(!p)
{
if(index >= memCount)
break;
for(int j = 0; j < 16; j++)
{
if((index < memCount) && Mem[index])
{
delete [] Mem[index];
Mem[index] = NULL;
index++;
}
else
{
break;
}
}
s = ::HeapCompact(GetProcessHeap(), 0);
BOOL b = SetProcessWorkingSetSize(GetCurrentProcess(), -1, -1);
if(!b)
{
DWORD dw =::GetLastError();
dw = dw;
}
}
}while(!p);

if(!p)
{
p = ::VirtualAlloc(NULL, MEM_1_K * MEM_1_K, MEM_COMMIT | MEM_RESERVE|MEM_LARGE_PAGES, PAGE_READWRITE);
if(!p)
{
DWORD dw = ::GetLastError();
::printf("Failed to allocate 1M memory!");
::getchar();
}
}
return 0;
}
  • 打赏
  • 举报
回复
罗平 2012-02-09
用 new delete 试试
  • 打赏
  • 举报
回复
SuperLy 2012-02-09
如果确认64k的块都释放了,那么就是内存碎片问题。
我们公司的项目也遇到了这种问题,分配了数千个500~600k的空间,全部释放后再new几百个800k的空间;反复个一定次数后,new 800k空间就可能会失败。
解决的方法是采用内存池,申请一块/多块相对较大的内存空间,自己来管理使用,尽量减少系统本身的空间申请/释放次数。

  • 打赏
  • 举报
回复
发帖
硬件/系统
加入

2613

社区成员

VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
申请成为版主
帖子事件
创建了帖子
2012-02-09 11:04
社区公告
暂无公告