【问题标题】:boost::multi_array resize exception?boost::multi_array 调整大小异常?
【发布时间】:2010-03-22 14:27:21
【问题描述】:

我正在尝试确定 boost::multi_array 构造函数或 resize 方法是否会引发 bad_alloc 异常(或其他指示分配或调整大小失败的异常)。我在任何地方的文档中都找不到此信息。

澄清(从评论中添加):

这是一种科学算法,如果分配失败,它可以退回到内存密集度较低(较慢)的方法。基本上,有两个动态分配的 3 维数组来保存查询中所有基因对之间的“距离”(相关性)以及大量数据集中每个数据集的交叉验证集中的所有基因。较慢的方法会根据需要重新计算每个距离。这是针对现有 Java 实现的 C++ 版本的,它实现了这两种方法,并且会因内存不足异常而回退。我真的不希望内存用完。

【问题讨论】:

    标签: c++ boost boost-multi-array


    【解决方案1】:

    第一个:(回答真正的问题):由于它使用动态分配的内存,是的,它可以抛出 std::bad_alloc(我从未见过 boost 翻译 std::bad_alloc 异常;这会很疯狂这样做)。

    第二次:(对您的说明进行评论):您确实需要可用物理内存的信息来优化算法在运行时的性能。但是,您不能依赖std::bad_alloc 来确定您有多少可用内存,因为现代操作系统使用诸如 overcommit 之类的东西,这意味着:它们(几乎)永远不会返回失败的分配尝试,但是相反,只是给你一些“记忆”,当你真正尝试访问它时,它只会失败。

    在 Java 中,这可能会起作用,因为 VM 正在为您做很多事情:它尝试分配一些连续的内存块,并根据可用的物理内存和可用的物理内存未使用内存来决定是否应该对 GC 施加更多压力,或者只是分配更大的垃圾。此外,出于性能原因,您需要考虑到虚拟内存和物理内存是完全不同的概念。

    如果您需要针对此类情况对算法进行性能优化(这很可能是必要的,具体取决于您的工作领域),您需要检查特定于平台的函数,这些函数可以告诉您“现实世界”的样子。

    【讨论】:

    • 见我上面的评论,该算法由原始研究人员用Java实现,支持两种方法。如果无法分配足够的内存,则使用较慢的内存。我希望为 C++ 版本重新创建此行为,尽管我通常不希望内存不足。当我们发现我的 C++ 实现在内存方面比旧的 Java 更有效时,我们已经摆脱了对程序使用的另一种算法的这种回退。
    【解决方案2】:

    没有明确的异常规范是故意的。有关说明,请参阅 this 小节。此外,请注意,没有明确的规范意味着对函数可以抛出的异常类型没有限制。因此,至少,在内存耗尽或项目对象复制失败的情况下,ctor 和 resize 函数可以抛出异常。

    您可能感兴趣的一些启发 Boost 的通用参考是:

    【讨论】:

    • @gimpf:不,但缺少相同的东西可能让他感到困惑。
    • 可能会。我希望澄清。
    【解决方案3】:

    为什么不测试呢?很容易传递一个高得离谱的值来生成异常。

    另一方面,如果确实产生了这个异常,你打算怎么做? std::bad_alloc 是一种你通常无法在微观层面处理的异常......

    例如,在网络服务器上,您通常会执行一些清理操作(回滚数据库事务?),然后向用户返回 500 错误。

    但是当内存耗尽时,你可以安全地做很多事情,因为如果你不想再次撞到你知道靠近的内存墙,你必须小心行事:)

    【讨论】:

    • 这是一种科学算法,如果分配失败,它可以退回到内存密集度较低(较慢)的方法。基本上,有两个动态分配的 3 维数组来保存查询中所有基因对之间的“距离”(相关性)以及大量数据集中每个数据集的交叉验证集中的所有基因。较慢的方法会根据需要重新计算每个距离。这是针对现有 Java 实现的 C++ 版本的,它实现了这两种方法,并且会因内存不足异常而回退。我真的不希望内存用完
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多