2013-09-28 57 views
2

我需要分配一个相当大的内存块(或多块) - 几千兆字节。但是,如果我尝试分配一个浮动阵列超过5.32元素(〜2 GB),我得到一个运行时错误:动态内存分配的限制

terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc

这是确定的:

float* d = new float[532000000]; 

但这是坏的(bad_alloc的除外):

float* d = new float[533000000]; 

然后我试图分配另一个阵列除了第一个。发现第二个float阵列的最大尺寸为元件(〜748Mb)。

这是确定的:

float* d = new float[532000000]; 
float* e = new float[196000000]; 

这是不好:

float* d = new float[532000000]; 
float* e = new float[197000000]; 

我想知道什么是在应用程序中分配的内存的限制,以及如何避免呢?如何使用虚拟内存?

我的系统 - 32位的Ubuntu 12.10,编译器 - GCC 4.7,内存 - 8GB(〜6.5 GB可用)

+0

您正在32位或64位平台上运行吗? –

+0

看起来像一个地址空间碎片问题。这强烈暗示它是一个32位平台。 – Mysticial

+0

@OliCharlesworth,32位(添加到主题) – gorill

回答

5

你打的虚拟地址空间的限制;即使您有足够的物理RAM(即操作系统可能可以通过PAE访问,使用36位指针),但在32位系统上,每个进程仍具有32位虚拟地址空间,这意味着每个进程都无法映射在内存中超过4 GB的内存。

由于通常将虚拟地址空间的上半部分(或上部1 GB,它依赖于内核设置)保留给内核,因此通常将分配限制设置为〜2 GB,虚拟地址空间碎片可以降低这个数字。

有各种解决方法(例如,在Windows上,可以使用大于4 GB的内存映射文件,一次只能映射其中的一部分;可能在Linux上也可以这样做),但目前最简单解决方案就是转移到64位操作系统并重新编译64位应用程序。

+0

*移动到64位操作系统*如果进程仍然是32位,这是否工作? –

+0

@ ta.speot.is:它可以给它多一点的呼吸空间(操作系统的东西被移动到上半部分的64位虚拟地址空间,所以用户进程可以占用完整的32位虚拟地址空间),但是实际上64位地址空间的好处是你必须重新编译64位程序。 –

+0

64位系统有没有限制?我可以使用所有可用的物理内存吗? – gorill