这些天我有很大的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的连续数据结构。

这意味着您必须明确使用 PAE Windows上的设施或 Linux上的等效设施手动交换叠加层。这不一定很难,但需要一些时间才能开始工作。

或者你可以得到一个有大量内存的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位允许你。

Rob指出,VirtualAlloc for Windows是一个很好的选择,匿名文件映射也是如此。但是,特别是关于你的问题,答案是“if C或C ++”。可以分配,答案是没有这个,即使在WIN7 RC 64上也不支持

在exe文件的PE / COFF规范中,指定HEAP保留和HEAP提交的字段是32位数量。这符合Windows CRT中当前堆实现的物理大小限制,只有4GB。因此,没有办法从C / C ++中分配超过4GB(技术上,CreateFileMapping和VirtualAlloc / VirtualAllocNuma等的OS支持工具......不是C或C ++)。

此外,BE AWARE 有底层x86或amd64 ABI构造称为页面表。这个 WILL 实际上做了你所关注的事情,为更大的请求分配更小的块,即使这在内核内存中很满意,但对整个系统有影响,这些表是有限的。

如果您在如此盛大的声明中分配内存,建议您根据分配粒度(VirtualAlloc强制执行)进行分配,并确定可选标志或方法以启用更大的页面。

4kb页面是386的初始页面大小,不明显的是pentium增加了4MB。今天, AMD64 (AMD软件优化指南) Family 10h Processors)的最大页表条目大小为1GB。这意味着你的情况,假设你刚刚做了4GB,它只需要内核目录中的4个唯一条目来定位\分配和许可你的进程的内存。

微软也发布了这个手册,阐明了应用程序内存的一些细节,它适用于Vista / 2008平台和更新版本。

内容

介绍。 4

关于内存管理器4

虚拟地址空间。 5

核心虚拟动态的动态分配 地址空间。 5

x86架构的详细信息。 6

64位体系结构的详细信息。 7

内核模式堆栈在x86中跳跃 架构。 7

使用多余的池内存。 8

安全性:地址空间布局 随机化。 9

ASLR对图像载荷的影响 地址。 9

ASLR的好处.. 11

如何创建基于动态的 图片。 11

I / O带宽。 11

Microsoft SuperFetch。 12

页面文件写入。 12

内存管理器和协调器的协调 缓存管理器13

预取样式聚类。 14

大文件管理15

休眠和待机。 16

高级视频模型16

NUMA支持17

资源分配。 17

默认节点和亲和力。 18

中断亲和力。 19

NUMA感知系统功能 应用。 19

NUMA感知系统功能 驱动程序。 19

寻呼。 20

可扩展性。 20

效率和并行性.20

页框号和PFN数据库。 20

大页面。 21

缓存对齐的池分配。 21

虚拟机。 22

负载均衡。 22

其他优化。 23

系统完整性。 23

硬件错误的诊断。 23

代码完整性和驱动程序签名。 24

错误检查期间的数据保留。 24

你应该做什么24

对于硬件制造商。 24

对于驱动程序开发人员24

对于应用程序开发人员25

对于系统管理员。 25

资源。 25

如果系统上size_t大于32位,则清除了第一个障碍。但是C和C ++标准不负责确定对new或malloc的任何特定调用是否成功(除了具有0大小的malloc)。这完全取决于操作系统和堆的当前状态。

像其他人一样,获得64位机器是可行的方法。但即使在32位机器的英特尔机器上,如果你的操作系统和你的CPU支持 PAE 的。不幸的是,32位WinXP没有这样做(32位Vista?)。 Linux允许你默认执行此操作,但是你将被限制在4gb区域,即使使用mmap(),因为指针仍然是32位。

您应该做的是让操作系统为您处理内存管理。进入一个可以处理大量RAM的环境,然后将XML文件读入(a)数据结构,并让它为您分配空间。然后对内存中的数据结构进行操作,而不是对XML文件本身进行操作。

即使在64位系统中,你也无法控制程序的哪些部分实际位于RAM,缓存中,或者被分页到磁盘,至少在大多数情况下,因为操作系统和MMU自己处理这个问题。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top