这些天我有很大的ram,我想知道,有可能分配一块大于4GB的单块内存吗?或者我需要分配一堆较小的块并处理它们之间的切换?
为什么???我正在处理一些openstreetmap xml数据,这些文件非常庞大.我目前正在流式传输,因为我无法将它们全部加载到一个块中,但我对malloc或new的上限感到好奇.
简短回答:不太可能
为了使其工作,您绝对必须使用64位处理器.其次,它将取决于操作系统支持为单个进程分配超过4G的RAM.
从理论上讲,它是可能的,但您必须阅读内存分配器的文档.您也会更容易受到内存碎片问题的影响.
有关Windows内存管理的良好信息.
关于物理和虚拟内存布局的入门读物
您需要一个64位CPU和O/S构建,几乎可以肯定足够的内存,以避免颠覆您的工作集.一点背景:
32位机器(大体上)具有可以存储2 ^ 32(4,294,967,296)个唯一值之一的寄存器.这意味着32位指针可以处理2 ^ 32个唯一内存位置中的任何一个,这是魔法4GB限制的来源.
某些32位系统(如SPARCV8或Xeon)具有MMU,可以提供更多物理内存.这允许多个进程占用总计超过4GB的内存,但每个进程仅限于其自己的32位虚拟地址空间.对于查看虚拟地址空间的单个进程,32位指针只能映射2 ^ 32个不同的物理位置.
我不会详细介绍,但这个演示文稿(警告:powerpoint)描述了它的工作原理.某些操作系统具有设备(例如在此描述的那些- 由于上面的FP)来操纵MMU并在用户级别控制下将不同的物理位置交换到虚拟地址空间.
操作系统和内存映射I/O将占用一些虚拟地址空间,因此并非所有4GB都必须可用于该进程.例如,Windows默认采用2GB,但如果在启动时调用/ 3G开关,则可以设置为仅占用1GB.这意味着这种32位体系结构上的单个进程只能在内存中构建一个小于4GB的连续数据结构.
这意味着您必须明确使用Windows上的PAE工具或Linux上的Equivalent工具来手动交换覆盖.这不一定很难,但需要一些时间才能开始工作.
或者,您可以获得具有大量内存的64位盒,这些问题或多或少都会消失.具有64位指针的64位架构可以构建具有多达2 ^ 64(18,446,744,073,709,551,616)个唯一地址的连续数据结构,至少在理论上是这样.这允许构建和管理更大的连续数据结构.
内存映射文件的优点是你可以打开比4Gb大得多的文件(在NTFS上几乎无限!)并且有多个<4Gb内存窗口.
它比打开文件并将其读入内存要高效得多,在大多数操作系统上它使用内置的分页支持.
对于64位操作系统(以及具有大量内存的计算机),这应该不是问题.
如果malloc无法应对,那么操作系统肯定会提供允许您直接分配内存的API.在Windows下,您可以使用VirtualAlloc API.
这取决于你正在使用哪个C编译器,以及在什么平台上(当然),但没有根本原因你不能分配最大块的连续可用内存 - 这可能比你需要的少.当然,您可能必须使用64位系统才能解决大量RAM ...
请参阅Malloc了解历史和细节
在alloc.h中调用HeapMax以获得最大的可用块大小
您是否考虑过使用内存映射文件?由于您正在加载非常大的文件,看起来这可能是最好的方法.
这取决于操作系统是否会为您提供允许寻址大于4GB的内存的虚拟地址空间以及编译器是否支持使用new/malloc分配它.
对于32位Windows,您将无法获得大于4GB的单个块,因为指针大小为32位,因此将虚拟地址空间限制为4GB.(您可以使用物理地址扩展来获得超过4GB的内存;但是,我相信您必须将该内存映射到4GB的virtualaddress空间)
对于64位Windows,VC++编译器支持64位指针,虚拟地址空间的理论限制为8TB.
我怀疑这同样适用于Linux/gcc - 32位不允许你,而64位允许你.