【问题标题】:Limits on dynamic memory allocation动态内存分配的限制
【发布时间】:2013-09-28 23:36:03
【问题描述】:

我需要分配相当大的内存块(或多个块)- 几 GB。但是,如果我尝试分配一个包含超过 532000000 个元素(~2 Gb)的 float 数组,则会出现运行时错误:

在抛出 'std::bad_alloc' 的实例后调用终止 什么():std::bad_alloc

没关系:

float* d = new float[532000000];

但这很糟糕(bad_alloc 例外):

float* d = new float[533000000];

然后我尝试分配除第一个数组之外的另一个数组。发现第二个 float 数组的最大大小为 195000000 个元素(~748 Mb)。

没关系:

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,RAM - 8GB(约 6.5 Gb 可用)

【问题讨论】:

  • 您是在 32 位还是 64 位平台上运行?
  • 看起来像地址空间碎片问题。这强烈表明它是一个 32 位平台。
  • @OliCharlesworth,32 位(添加到主题中)

标签: c++ memory memory-management heap-memory


【解决方案1】:

你达到了虚拟地址空间的限制;即使你有足够的物理内存(操作系统可能可以通过 PAE 访问,使用 36 位指针),在 32 位系统上,每个进程仍然有一个 32 位虚拟地址空间,这意味着每个进程不能映射内存超过 4 GB。

由于通常虚拟地址空间的上半部分(或上半部分 1 GB,这取决于内核设置)是为内核保留的,因此您通常会将分配限制设置为 ~2 GB,并且虚拟地址空间碎片可以降低这个数字。

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

【讨论】:

  • 迁移到 64 位操作系统如果进程仍然是 32 位,这是否可行?
  • @ta.speot.is:它可以给它更多的呼吸空间(操作系统的东西被移动到上半部分 64 位虚拟地址空间,所以用户进程可以占用完整的 32 位虚拟地址空间),但要真正受益于 64 位地址空间,您必须为 64 位重新编译程序。
  • 对 64 位系统有限制吗?我可以使用所有可用的物理内存吗?
  • @gorill:一个失控的进程在被 OOM 杀手杀死之前设法消耗了我 Linux 机器上几乎所有的物理内存和交换空间,所以我想是这样。
猜你喜欢
  • 2012-06-27
  • 1970-01-01
  • 1970-01-01
  • 2014-10-03
  • 2010-12-26
  • 2018-09-06
  • 2012-01-13
  • 1970-01-01
  • 2021-02-15
相关资源
最近更新 更多