免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2845 | 回复: 3
打印 上一主题 下一主题

Linux下进程无法申请超过2G的连续空间(请注意,这里是指连续空间) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-03-27 23:46 |只看该作者 |倒序浏览
实验环境:
Suse Enterprise Server 9      内核是 2.6.*, 小版本号记不清楚了.  是在公司机器上运行的.
在家里的虚拟机上又试了一下, 也是一样的. 下面是Linux号
linux:~ # uname -a
Linux linux 2.6.13-15-default #1 Tue Sep 13 14:56:15 UTC 2005 i686 athlon i386 GNU/Linux

最近发现了Linux分配内存的另外一个怪异的现象: Linux进程无法直接分配接近3G的连续空间.

见下面小样例:  申请1K的内存, 得到的指针是804a008

#include <stdio.h>
#include <stdlib.h>
#define SIZE  1*1024     //1K
int main()
{
        void *pPtr = 0;

        pPtr = malloc(SIZE);
        printf("pPtr = %lx, size = %d\n", pPtr, SIZE);
        return 0;
}

linux:~ # ./test_mem_start
pPtr = 804a008, size = 1024

但是如果分配1M或者大于1M内存,则得到的指针为40151008
#include <stdio.h>
#include <stdlib.h>
#define SIZE  1*1024*1024        //1M
int main()
{
        void *pPtr = 0;

        pPtr = malloc(SIZE);
        printf("pPtr = %lx, size = %d\n", pPtr, SIZE);
        return 0;
}

linux:~ # ./test_mem_start
pPtr = 40151008, size = 1048576

因为高内存3G~4G被内核映射, 因此实际上能够申请到的最大连续空间为2G, 最大的空间为3G.

这个在SuseLinux 9/10上都验证过,没有验证过其他的发行版. 不过相信这个问题应该跟发行版没有关系.

哪位大侠可以解释一下,谢谢

论坛徽章:
0
2 [报告]
发表于 2007-03-28 12:42 |只看该作者
> 因为高内存3G~4G被内核映射, 因此实际上能够申请到的最大连续空间为2G

为什么是2G呢?


还有,压根儿就没看懂你在说啥, 代码中哪有跟2G或者“接近3G” 的“连续”地址有关的东西?

论坛徽章:
0
3 [报告]
发表于 2007-03-28 21:39 |只看该作者

已经弄明白了!!

今天打电话咨询了一下Suse的工程师, Linux进程内存管理就是这样的.

没看明白可能是我没有说得太清楚.

你可以看一下, 为什么我分配1M内存,得到的起始地址就是0x40151008, 0x40000000是1G.
进程的0xC0000000后面的地址为内核映射, 从0x4000000~0xC0000000中间是多少的虚拟地址??

其实我的问题很简单,为什么分配1K内存得到的地址是0x804a008, 而分配1M内存得到的地址是0x40151008.

论坛徽章:
0
4 [报告]
发表于 2007-03-29 19:57 |只看该作者
应用程序是从0x8048000开始,那是由linker定的,具体数值在一linker脚本定的,具 体在哪忘了,只在linux上是这样,到其它的平台上,可能就是另外一个值了,这只是个约定。0x804a008到0x8048000之间是程序的.text,.data,.bss等内容。

而0x40000000那是由linux内核定的,2.6.9以前的默认开始地址。为什么是由内核定?因为你分配了1M的内存,好像是大于了512K以后,glibc的malloc就用mmap()向内核要内存了。而小于512K的时候好像是用brk()向内核申请内存,所以开始地址离0x8048000很近。

mmap()的开始地址,在2.6.9以后,在/proc中有个开关,可以改变这个地址,新的地址是从0xc0000000开始倒数128到129M中的 一个页对齐的数作为开始地址,具体的请看ULK3的最后一章吧。

从0x40000000~0xc0000000之间是mmap,stack,env,arg。mmap从小向大增涨,从0xc0000000开始为,env,arg(具体顺序记不清了),主程序的stack。

Maybe I'm wrong,FIXME.

BTW,这一点也不怪异。
BTW2,因为高内存3G~4G被内核映射, 因此====>>实际上能够申请到的最大连续空间为2G, 最大的空间为3G.<=====什么意思?

[ 本帖最后由 12013396 于 2007-3-29 20:09 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP