【问题标题】:Strange malloc behavior won't allow more that 2GB memory allocation on a 64 bit process奇怪的 malloc 行为不允许在 64 位进程上分配超过 2GB 的内存
【发布时间】:2013-04-10 16:39:07
【问题描述】:

这个问题涉及我正在开发的一个程序。

我正在开展一个项目,该项目要求不通过网络发送行集或大于 2GB 的行(网络无法以大于 2GB 的组发送数据)。我已经对代码进行了所有适当的更改,因此它不会发送这个/这些组,但现在我正在尝试构建测试用例。

我已经构建了一个测试,它只创建了不到 10 亿行占用超过 2 GB 的行。程序会在这些行通过网络发送之前正确过滤掉它们。

我遇到的问题是我需要创建一个单行,该行将包含具有单个字符串的列或列集合,在该行内,该行包含字符串,其中该行的大小大于2GB。但是当字符串开始占据接近2GB时,malloc返回NULL

我做了一些研究,发现这可能是因为我没有足够的连续内存,所以我开始添加更多具有较小字符串的列。我已经将2GB 字符串拆分为64 列,这样它就不必一次分配那么多。我仍然遇到同样的问题,我开始怀疑我忽略了一些东西。

它是 64 位 Windows 7 系统上的 64 进程。 8GB 内存。 (不过我也在一台 64 位、24GB RAM 的 red hat 机器上测试过)

有没有人知道为什么系统在接近2GB时不会分配程序内存?

附:我还查看了每个进程可以在 64 位系统上分配的内存,它超过了100TB。考虑到这么多,当我接近 2GB 时我无法分配的事实真的让我感到困惑。

【问题讨论】:

  • 您是否使用足够大的整数类型来存储大小?我假设您运行的是 64 位操作系统,而不仅仅是 64 位硬件?
  • @TopGunCoder: gcAllowVeryLargeObjects 用于 .NET 框架。这是一个 C++ 应用程序,对吧?我有相同的配置,并且在 10GB 的情况下运行良好(尽管分配需要一段时间)。
  • 那个仍然表现出这种行为的最小的、可编译的程序怎么样?抓紧时间写吧。如果该程序没有显示错误,则问题出在代码中的其他地方。如果是这样,找出问题所在会容易得多。
  • @TopGunCoder:不,不要重新创建实现!只需编写一个非常小的程序,尝试以类似于您的实际程序的方式分配内存。如果可行,那么您的问题可能出在内存分配以外的其他地方,您可以停止查看配置等。
  • 我发现了问题所在!就在我准备继续之前,我注意到有人更改了变量类型,在之前的更改中,从 32 unsigned 更改为 signed。因此,当这被我的大行溢出并传递到我拥有的 alloc 包装器中时,负位将转移到无符号 64 的负位......创建大量内存,它试图分配!谢谢大家的帮助!!如果你们没有提出如此彻底的建议,我不会注意到这种微妙之处:D:D:D:

标签: c++ linux windows unix memory-management


【解决方案1】:

在对我遇到此问题的大量代码进行大量探索之后,我注意到传递给calloc(uint_64) 的大小是由一个返回有符号整数的函数计算的。由于这个数字被溢出,当它被编译器转换为uint_64 时,设置了最大位。这当然会导致 calloc 尝试分配大量内存。

当然有几种可能的解决方案:

  1. 将 size 函数的返回类型更改为 uint_32(这对我的代码库和时间限制来说太大了)
  2. 将 size 函数的结果转换为 uint_32,然后将其传递给 calloc(我选择的选项,以暂时绕过大分配)

我希望这最终对其他人有所帮助,

【讨论】:

  • 为什么不返回 size_t 的尺寸?
猜你喜欢
  • 2013-03-25
  • 2014-02-03
  • 2011-10-12
  • 1970-01-01
  • 2015-10-23
  • 2019-04-01
  • 2013-12-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多