【问题标题】:Get the remaining available memory in standard C++11?在标准 C++11 中获取剩余的可用内存?
【发布时间】:2013-02-07 03:05:25
【问题描述】:

是否可以在标准 C++11 中获取系统(x86、x64、PowerPC / Windows、Linux 或 MacOS)上剩余的可用内存而不会崩溃?

一种天真的方法是尝试从太大的大小开始分配非常大的数组,每次失败时捕获异常并减小大小直到没有抛出异常。但也许有更有效/更聪明的方法......

编辑 1:实际上我不需要确切的内存量。我想知道大约(100MB 的错误栏)我的代码在启动时可以使用多少。

编辑 2: 你觉得这段代码怎么样?在我的程序开始时运行它是否安全,否则可能会损坏内存?

#include <iostream>
#include <array>
#include <list>
#include <initializer_list>
#include <stdexcept>

int main(int argc, char* argv[])
{
    static const long long int megabyte = 1024*1024;
    std::array<char, megabyte> content({{'a'}});
    std::list<decltype(content)> list1;
    std::list<decltype(content)> list2;
    const long long int n1 = list1.max_size();
    const long long int n2 = list2.max_size();
    long long int i1 = 0;
    long long int i2 = 0;
    long long int result = 0;
    for (i1 = 0; i1 < n1; ++i1) {
        try {
            list1.push_back(content);
        }
        catch (const std::exception&) {
            break;
        }
    }
    for (i2 = 0; i2 < n2; ++i2) {
        try {
            list2.push_back(content);
        }
        catch (const std::exception&) {
            break;
        }
    }
    list1.clear();
    list2.clear();
    result = (i1+i2)*sizeof(content);
    std::cout<<"Memory available for program execution = "<<result/megabyte<<" MB"<<std::endl;
    return 0;
}

【问题讨论】:

  • 对不起,这次“可能”的两个可能结果中的“否”已经出来了。
  • 高度依赖平台,标准中没有处理。
  • 没有“标准”方法可以做到这一点。即使您描述的方法也可能不会返回有效结果。您必须使用特定于平台的功能。
  • 但至少,幼稚的方式会奏效吗?
  • 否 - 以 64 位平台为例,它允许运行 32 位软件。它有 32GB 内存,但 32 位程序无法访问那么多内存。或者考虑一个平台,管理员可以在该平台上对程序可以拥有的内存量实施配额。

标签: c++ exception memory memory-management c++11


【解决方案1】:

这高度依赖于操作系统/平台。您建议的方法甚至不需要在现实生活中起作用。在某些平台上,操作系统会授予您所有的内存请求,但在您使用它之前不会真正给您内存,此时您会获得 SEGFAULT...

该标准没有与此相关。

【讨论】:

  • Segfault 不会是一个可能的结果。在 Mac OS X 上,该进程将被挂起。在任何情况下,机器通常会首先开始“颠簸”。
  • @Potatoswatter:尝试一个 linux 机器,删除交换文件,分配一个足够大的动态数组并遍历它,例如第 4096 个字节以触及所有内存页面。至少在过去,它最终会死于 SEGFAULT
  • @DavidRodríguez-dribeas -- 那是 Linux,OSX 不同。正如您所说,它“高度依赖”。关键点是,在某些系统上,即使在虚拟内存中,也可以成功分配比可用内存更多的内存,其中“成功”意味着不会从 new 中抛出,或者来自 malloc 的非空指针。直到“成功”分配了虚假的内存量之后,问题才可能出现。
  • @DavidHammen:对.... 我不确定为什么 Mac OS X 会如此坚持。我只是提到这种特殊行为在某些操作系统中会失败(也许我应该在那里明确提到 linux?)。我没有提到 OSX,问题显然是多平台的。
  • @DavidRodríguez-dribeas 删除实时交换文件是支持禁用虚拟内存的方法吗?听起来如果你这样做,机器注定会崩溃。它已经包含的换出页面呢?
【解决方案2】:

在我看来答案是不,你不能在标准 C++ 中做到这一点。

您可以做的事情在How to get available memory C++/g++? 和那里链接的内容下讨论。这些都是平台特定的东西。它不是标准的,但它至少可以帮助您解决您正在处理的问题。

【讨论】:

    【解决方案3】:

    正如其他人所提到的,问题很难精确定义,更不用说解决了。硬盘上的虚拟内存算作“可用”吗?如果系统提示删除文件以获取更多硬盘空间,同时暂停你的程序怎么办? (这正是 OS X 上发生的情况。)

    系统可能实现了一个内存层次结构,当你使用更多时,它会变得更慢。您可以尝试通过在使用 C alarm 中断设施或 clocklocaltime/mktime 或 C++11 时钟设施时分配和初始化内存块来检测 RAM 和磁盘之间的性能悬崖。随着机器在从效率较低的资源中获取内存的压力下速度变慢,挂钟时间应该会过得更快。 (但这假设它没有受到其他任何进程(例如另一个进程)的压力。)您可能想告诉用户程序正在尝试什么,并将结果保存到可编辑的配置文件中。

    【讨论】:

      【解决方案4】:

      我建议改为使用可配置的最大内存量。由于某些平台会过度使用内存,因此很难判断您实际可以访问多少内存。假设您可以独占访问 100% 的可用内存也是不礼貌的,许多系统会运行其他程序。

      【讨论】:

        猜你喜欢
        • 2014-07-03
        • 2012-12-24
        • 2015-12-09
        • 1970-01-01
        • 2012-01-20
        • 1970-01-01
        • 1970-01-01
        • 2017-12-29
        • 2017-12-14
        相关资源
        最近更新 更多