您的位置:首页 > 其它

malloc最多能分配多少内存

2014-06-12 14:36 288 查看
关键词:

学会利用 vmmap

学会自己***简单的测试用例

可以通过选项改变默认大小

还有选择多线程调试的方式不一样,最大的内存申请空间也不一致。

----

http://bbs.csdn.net/topics/190098526





malloc最多能分配多少内存 (VS6.0和VS2005得到的结果不同)

.测试程序如下,在VS6.0和VS2005中运行可知

#include <stdio.h>

#include <malloc.h>

int main(void)

{

unsigned int size = 1024u*1024*1987;

char *p = (char *)malloc(size);

if (p == NULL)

{

printf("out of memory\n");

return;

}

}

在VS6.0下可分配1024*1024*1987的内存

在VS2005下测试程序最多能分配1024*1024*1656的内存

由于用户分区默认为2G,因此应该能分配接近于1024*1024*2048的内存

当然由于这是在堆中分配的内存,应该有部分被其他占用了,因此VS6.0应该是比较合理的结果

但为什么VS6.0和VS2005产生的结果不同呢

我怀疑是编译选项的问题,谁能帮我解答一下?

由于我在做一个DBMS,需要接受很多的连接以及执行大量的处理,我想测试最大能开到的缓冲区内存数目

而我的程序是用VS2005编译的,这样就浪费掉了1024*1024*331的空间





cceczjxy 等级:

结帖率:100%

62 #2 得分:10 回复于: 2007-11-14 18:10:25

char *p = (char *)malloc(size);

这样分配它是找最大连续的空间,

就是空闲空间,如果不和它向连,也不能分配.

所有,你有嗯楼上的测试程序应该能多分配不少

bbisonic 等级:

结帖率:100% #3 得分:0 回复于: 2007-11-14 18:44:57

测了一下lonecrystal的程序,打出结果

MAX alloc size = 2110222336

与2G的差距只有37261312

这块内存是在main开始处分配的,难道在堆空间某处系统分配了一块内存导致了碎片?

还有,我主要想弄清是什么编译选项会导致VC6.0与VS2005的不同?谢谢!

tanmeining 等级:

结帖率:100% #7 得分:3 回复于: 2007-11-15 01:31:07

#include <stdio.h>

#include <stdlib.h>

main()

{

int MB = 0;

while (malloc (1 << 20))

{

++MB;

printf(" Allocated %d Mb total \n", MB);

}

}

总共分配的内存量取决于交换区和你的系统配置中的进程限制,如果实际分配的内存块小于1M字节,你实际上得到的内存要比这个多些...

loops 等级:

结帖率:94.12%

#8 得分:50 回复于: 2007-11-15 09:30:03

我的VC2005上1024*1024*1987也可以,这跟vc6是一样的,一旦改成1988就不行。

如果code generation里面选择multi-threaded DLL会影响到这一点。

而且,CrtMainStartUp里面就有分配内存的行为,比如为你的命令行参数分配内存等等。

还可能有dll的问题,但是这个我不太清楚是否dll的地址空间跟你的程序一样。





jsjl2008 等级:

结帖率:79.17% #10 得分:1 回复于: 2007-11-15 14:23:34

X86分页边界是4K,物理内存是以页面方式提交的

可能一4K*N来分配为比较好的方式,内存块可以连续

但是/STACK(堆栈)好象默认是1M,这么大的空间合适?

结帖率:100% #11 得分:0 回复于: 2007-11-15 18:57:10

我分配500M内存后,查看了下进程空间,确实是连续的内存被

C:\WINDOWS\WinSxS\x86_Microsoft.VC80.DebugCRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_f75eb16c\MSVCR80D.dll

给割断成1.7G和262M两大块,这里使用的是多线程调试DLL

00420000 Private 4194304 3 -RW- Thread Stack

00820000 Free 262012928

10200000 Image 1179648 7 ERWC C:\WINDOWS\WinSxS\x86_Microsoft.VC80.DebugCRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_f75eb16c\MSVCR80D.dll

10320000 Private 524292096 1 -RW-

2F721000 Free 1212936192

现在使用多线程DLL就能分到1.9G左右的空间

00420000 Private 4194304 3 -RW- Thread Stack

00820000 Private 524292096 1 -RW-

1FC21000 Free 1476128768

77BE0000 Image 360448 7 ERWC C:\WINDOWS\system32\msvcrt.dll

77C38000 Free 5210112

78130000 Image 634880 9 ERWC C:\WINDOWS\WinSxS\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.163_x-ww_681e29fb\MSVCR80.dll

781CB000 Free 73617408

这两个DLL在进程中加载的位置导致了最大连续内存的差异

有谁知道DLL加载位置的规则吗?

---

Q顺便问一下:你用什么工具查看内存情况的?

A【】用的就是<Windows核心编程>上的VMMap的例子

结帖率:100% #17 得分:0 回复于: 2007-11-19 17:08:56

问题基本弄清楚了,我程序中的进程空间被comctl32.dll给隔成两部分了

对于系统的DLL而言,每个DLL都有其默认加载的基地址,WINDOWS能够保证各个DLL在进程空间中互不重叠,因此,你不应手动去改变系统DLL的基地址

当然,如果是用户创建的DLL的话,你应该使用Rebase程序使得DLL紧凑一些

既然改变不了系统DLL的基地址,我现在暂时也没想到什么更好的解决方案.

另外,我发现某些DLL基地址间的空间仍有很大,是因为这些空间预留给了其他系统DLL?

还有,为什么加载DLL时要预留整个DLL大小的空间,而不是像链接静态库那样只预留出需要调用函数占据的页面大小呢?



结帖率:100% #20 得分:1 回复于: 2007-11-21 19:32:26

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dngenlib/html/awewindata.asp

结帖率:100% #21 得分:1 回复于: 2007-11-22 09:01:35

1.通过设置,32位程序的最大可用内存可提升至3G.而不是只有2G.包括编译时设置和系统启动参数设置.

2.32位系统通过PAE也可以支持超过4G的内存.在没使用PAE的时候,系统只认3G内存而不是4G.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: