QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1264|回复: 14

怎么访问大于1GB内存

[复制链接]
发表于 2005-6-23 00:01:27 | 显示全部楼层 |阅读模式
机器配有4GB内存,可是C程序一次只能malloc 1GB内存,C++也是。请问能不能一次开辟大于1GB的数组,或者能通过什么方式访问大于1GB的内存?
发表于 2005-6-23 09:08:04 | 显示全部楼层
这不是访问吧?应用程序能申请到的内存不能大于数据段的最大值,我想gcc里应该可以编译指定最大的段大小,不过我没查过不知道是那个key。但只是这样你的程序还不能跑,操作系统的ulimit设定规定了应用程序所能使用的最大内存空间,可以用ulimit命令来检查和修改。 如果你需要这么大的空间,推荐用server版的那些linux,那些多半都修正过了,允许程序拥有非常大的空间。
回复

使用道具 举报

 楼主| 发表于 2005-6-24 18:45:31 | 显示全部楼层
谢谢你的回复。

我的用的是RHEL AS3.0,昨天发现可以开2GB的数组。一个指针是4个字节,最大也就能开4GB吧,但是如果系统有8GB的内存那能访问得到吗?

操作系统可以访问大于4GB的内存,但是我的应用程序能申请到大于4GB的内存吗?

ulimit -a的输出显示是 data seg size 是ulimited。
回复

使用道具 举报

发表于 2005-6-26 16:58:44 | 显示全部楼层
不懂,这和访问4G内存有什么关系??
程序中所有的内存地址都是虚拟地址,在OS中经过映射后才转为物理地址,即使这样在32位机的情况下寻址空间至多为4G,在64位机的情况下(我记不清了,好像是36位寻址)就是64G,你的应用程序所能得到的地址只会在这些之内,你说系统有8G内存的话是物理内存吧,跟程序应该没有太大关联。
不对请指教,时间长了,概念不是太清了。
回复

使用道具 举报

发表于 2005-6-26 17:39:14 | 显示全部楼层
访问到多大的内存不是你的应用程序关心的事情 应该是操作系统的事情
如果一次malloc只能拿到1G 那就申请四次吧 哈哈
回复

使用道具 举报

发表于 2005-6-26 18:17:56 | 显示全部楼层
intel的p2以上的cpu确实可以通过一种特殊的寻址方法支持上48G内存,
我并不清楚kernel是否允许开这种寻址模式。

如果工作在普通的32位模式下,应用程序理论上data区的上限是3G,不过能到2G就
不错了,而且,由于地址空间的限制,你的系统管理4G以上的物理内存是不可能的,因为
那个时候内核如果不使用什么特殊的寻址方式,CPU没法寻址到4G以上的内存。
回复

使用道具 举报

 楼主| 发表于 2005-6-26 22:53:30 | 显示全部楼层
[quote:9fbef8cc6e="kakuyou"]intel的p2以上的cpu确实可以通过一种特殊的寻址方法支持上48G内存,
我并不清楚kernel是否允许开这种寻址模式。

如果工作在普通的32位模式下,应用程序理论上data区的上限是3G,不过能到2G就
不错了,而且,由于地址空间的限制,你的系统管理4G以上的物理内存是不可能的,因为
那个时候内核如果不使用什么特殊的寻址方式,CPU没法寻址到4G以上的内存。[/quote]
你的意思我理解,但是看Linux内核的资料(当然我没有全部看懂),最大寻址可以是很大的(具体多大记不清了,反正>4GB),而且我确实有一台8GB内存的P4,操作系统(rhelAS3)可以识别其8GB。

是不是我自己的程序能申请到的数据段最大是4GB?而操作系统可以通过其特殊的方式支持更大的内存?
回复

使用道具 举报

发表于 2005-6-27 09:12:10 | 显示全部楼层
deerlux, 我说了这里有两个限制
一是编译的时候 你使用malloc这样的数据堆的来源实际上是编译的时候为c基础环境初始化设定的某个数据段 大的段的处理和支持和小的段是不一样的 所以编译器需要指定
二是这个数据段的运行中的实现问题 如果系统限制你的段展开大小:比方说winnt就只支持2+2和1+3模型 你就不能有像4g这么大的数据可用
用server版的话 基本上就是放开了这个限制
没记错的话基本上现在32位芯片的地址都可以扩展到48位的 但实际上使用中除了cpu的寻址能力 还有主板设计的限制等等
回复

使用道具 举报

 楼主| 发表于 2005-6-27 11:16:40 | 显示全部楼层
wsm,你讲的这些我大致也明白了,那么请问具体到我现在这种平台上。Intel xeon CPU,8GB内存, RHELAS3,我能不能在C程序里面一次申请大于4GB的内存,如果能,怎样去申请?

malloc是行不通的,因为一个unsigned char *的大小是4,也就是说只能到4GB。从但是如果 真到了4GB我试验的结果是编译的时候给个warning,而运行的时候coredump
回复

使用道具 举报

发表于 2005-6-27 11:25:07 | 显示全部楼层
这个都要抱歉了 我没有具体做过这方面的事情
注意 malloc要的参数实际上是一个size_t 这是一个由平台决定的数据类型  如果coredump了 恐怕你需要联系redhat的人 讨论一下这个问题 你的内核是否真的管理起了那么大的内存空间
ps:希望你到时候能贴出来 让大家也了解一下
回复

使用道具 举报

 楼主| 发表于 2005-6-27 12:04:49 | 显示全部楼层
sizeof(size_t)输出也是4。

谢谢你的回复,我自己再查一下看看吧,那天在网上看到好象用mmap可以,但是我还没有找到具体的方法。
回复

使用道具 举报

发表于 2005-6-27 13:09:12 | 显示全部楼层
搞错了。

奔pro和它以上的cpu存在一种叫PAE的特殊寻址模式,它允许CPU访问
多达64GB的内存空间(36位)。新的2.6内核是完全支持这种模式。
不过,我看到的资料都没有明确的说明2.6内核下的用户进程是否允许
使用这种寻址模式,而2.4内核则明确的说明用户进程的地址空间还是
3GB。

你可以使用getrlimit和setrlimit察看data段的上限和更改它,具体
看man手册吧。
回复

使用道具 举报

发表于 2005-6-27 14:22:00 | 显示全部楼层
在kernel的mail list里找到了一篇对hugemem补丁的说明 大致意思如下
>4g的空间只是内核vmem映射的时候使用的 给用户的空间依然是32位的
因为很快会有64位整个环境出来 开发者不可能花力气去给用户创建一个36位的环境
现在使用大于4G的内存的办法 就是创建多个占用几个G空间的进程使用它
看来楼主要么改程序 要么就用64位环境吧
回复

使用道具 举报

 楼主| 发表于 2005-6-28 01:45:37 | 显示全部楼层
getrlimit 看RLIMIT_DATA的输出rlim_max和rlim_cur是4GB,但很显然我的一个进程是分配不了4G的空间的。

re: wsm

创建多个占用几个G空间的进程对我来说是比较适合的,因为用到并行的东西我都是用MPI做的,可以让其在一台机子上跑2-4个进程。改为64位系统现在来说不太现实,毕竟要用money去砸啊。
回复

使用道具 举报

发表于 2005-6-28 09:09:16 | 显示全部楼层
还有一种方法

创建数个上GB的共享内存,需要使用那个时就贴上那个。

我想,你肯定明白由于地址空间的限制,你是不能同时
访问它们的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-5 19:28 , Processed in 0.061773 second(s), 16 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表