malloc最多能分配多少内存

关键词:

学会利用 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. 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值