【问题标题】:Why is C++ heap allocation so slow compared to Java's heap allocation? [closed]为什么 C++ 的堆分配比 Java 的堆分配慢? [关闭]
【发布时间】:2013-05-10 04:32:51
【问题描述】:

我在 Java 和 C++ 中进行了小型测试,创建了大量非常小的对象(没有类成员,没有构造函数),Java 显然更快(我的意思是 C++ 似乎真的很慢)。我敢打赌这与 JVM 有关,但以何种方式?

编辑:

我使用的类在 C++ 中是这样的(因为我说没有类成员,在构造函数中没有做任何事情):

class foo{
    public:
        foo(){}
        ~foo(){}
}

在 Java 中:

public class Foo{
    public Foo(){}
}

我所做的小测试只是关于在一个循环中分配大量对象(连续大约 1000000000 个)。我通过 OpenJDK 实现使用了 GCC 4.7.2 和 Java 1.7,两者都在使用 Linux 的同一台机器上。

我敢打赌,它确实与内存池分配有关,这表明 JVM 拥有不需要的内存。

我仍然感到困惑,因为我认为 JVM 实际上会更慢,计算指针引用和分配内存。

【问题讨论】:

  • 这个问题无法回答。这取决于 C++ 编译器、JVM 版本、基准程序、平台……
  • Hotspot(我假设您正在使用)是一个优化运行时。对象内存分配现在如此之快,几乎被认为是免费的。但是,我没有看到您的 C++ 代码或您使用的编译器实现,因此我无法评论它的优化程度。
  • 你不是在这里比较苹果和苹果。对于这种情况,JVM 使用预先分配的内存池。 C++ 没有针对这种结构的预构建功能,而是向操作系统内存管理器查询 every 分配。人们用 C++ 编写一个提供 JVM 在这里所做的事情(内存池分配器)的系统并不少见。此外,这是一个合法的问题,所有的反对票都是 BS。
  • 虽然它可以受益于关于测试的具体实现和对它们进行的测试的更多细节,但这是一个最合理的问题 - 特别是,尽管有一些变体,两种语言的实现足够同质,只需少量警告即可回答问题。
  • @Dave 我认为典型的 C++ 实现不会要求操作系统进行每次分配。 mallocnew 有许多限制,这使得许多优化不可行,但至少 C 或 C++ 运行时库可以从操作系统分配更大的内存块,并为大多数分配分配内存块。

标签: java c++ performance heap-memory allocation


【解决方案1】:

在堆上分配许多小对象是一种情况,Java 的运行时通常比 C++(在大多数主流实现中)得到更好的开箱即用优化。每次使用new 在 C++ 中分配堆对象时,实现通常都会对操作系统进行系统调用(至少在大多数主流平台上,如 Linux 和 Windows)。在 Java 中,它通常是从 JVM 提供的内存池中分配的,该内存池是专门为在堆上分配 Java 对象而设计和优化的。

如果您使用特殊的内存池分配器,C++ 在大多数情况下可能会更快。 (此外,C++ 提供了在堆栈上分配对象的选项,当然,这比任何一个都快得多。)

一般来说,C++ 让您可以更精细地控制程序如何分配和管理内存。而 JVM 则受到 requires heap-allocated objects 和垃圾收集的实际 Java 语言规范的限制。但是,如果您使用 C++ 编写需要在堆上分配许多小对象的应用程序,您可能需要考虑使用内存池分配器。

【讨论】:

    猜你喜欢
    • 2015-10-15
    • 2019-12-07
    • 2016-10-28
    • 2011-06-14
    • 2013-03-03
    • 2012-12-23
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多