-1

我在一家公司工作,他们非常关心读写性能。而且我们在公司和 Geronimo 服务器中主要使用 Java 作为语言。

几天前,我们的团队和我们的架构师讨论了我们可以做些什么来提高性能。在那次会议上,我们的架构师提到我们需要做一些事情来解决“Java 中的大堆问题”和 Java 垃圾收集暂停。

他完全反对 Java GC 暂停和 Java 中的大堆问题。但坦率地说,我无法理解为什么 Java/JVM 中的这两件事或其他任何东西会导致如此糟糕的性能。我们的架构师主要支持 C++ 服务器和 C++ 语言。

现在我的问题是-我无法理解他为什么说由于 Java 中的大堆问题和垃圾收集暂停,Java 不适合我们需要确保读/写性能最高的用例-缺口。

谁能提供我详细的理解,为什么他在大堆问题和垃圾收集暂停方面反对 Java,与 C++ 相比,以及为什么他建议让我们使用 C++ 服务器和语言。我看到了其他各种 stackoverflow 帖子,以了解他为什么反对它,但不知何故,由于我缺乏深入的理解,我无法理解这些解决方案。所以任何一步一步的详细解释都会让我更清楚。

任何帮助将不胜感激。谢谢

4

2 回答 2

1

在 Java 中有两种处理垃圾暂停的方法。

  • 使用像 Zing 这样的并发收集器。他们可以获得 1-4 毫秒的最坏情况抖动,这比某些 C++ 程序更好,因为来自其他来源的抖动(即 GC 不是抖动的唯一原因)
  • 创建更少的垃圾并使用堆外内存。在 C++ 中,所有内容实际上都是堆外的,实际上,您可以在 C++ 中执行的任何操作都可以在 Java 中执行,即使它不那么自然。

这是一个真实高频交易系统的例子。它在没有交易时每天早上 5:00 进行一次 full GC,Eden 大小为 8 GB,大于一天产生的垃圾量。

http://vanillajava.blogspot.co.uk/2011/06/how-to-avoid-garbage-collection.html

OpenHFT/Java-Lang项目中,您可以做到这一点。

final DirectStore store = DirectStore.allocate(128L << 32); // give me 128 GB
final DirectBytes slice = store.createSlice();

// every record has say 128 bytes and a lock at the start so they can be locked individually
for(long l = 0; l < store.size(); l += 128) {
    slice.positionAndSize(l, 128);
    slice.busyLock(0L);
    // change something
    slive.writeLong(4L, l);
    slice.unlock(0L);
}

// when finished with the store
store.free(); // still no GCs.

所以在这个例子中,我创建并初始化了十亿条记录。这几乎不使用 JVM 堆,也不会触发任何 GC。

如果您担心代码可能无法在需要时编译,您可以通过执行来触发代码提前编译。进行一两个单元测试并练习关键代码,直到它编译为止。这通常可以在不到一秒钟的时间内完成。

简而言之,如果 GC 是一个问题,那么总会有解决方案。您可以使用 Java 开发解决方案,在盒子外部有 19 微秒的延迟,不会触发任何 GC(即使是次要的)

为什么他建议让我们使用 C++ 服务器和语言。

大多数开发人员不知道如何编写低延迟 Java。在 C++ 中,有更多的开发人员这样做,这就是使用 C++ 的原因。然而,阻止低延迟并不是语言的一个特性,只是在 Java 领域缺乏技能。

于 2013-07-14T21:40:37.530 回答
1

无论语言如何,动态内存分配和垃圾收集都会降低性能。使用静态或有限分配,不需要动态内存分配或垃圾收集。

C 和 C++ 语言不附带垃圾收集。动态内存分配由平台(操作系统或编译器库)提供。垃圾收集由程序员决定。这为程序员提供了灵活性。

Java带有动态内存分配和垃圾收集。语言提供的垃圾收集提出的一个问题是“垃圾收集何时运行?” 例如,当程序执行垃圾收集时,程序是否会暂停?还是将垃圾收集作为后台任务执行?

您将需要研究动态内存分配和垃圾收集以获得背景知识。接下来,请架构师澄清或解释他或她的推理。

另一个问题是 Java 被编译成一种称为 Java Byte Codes 的中间语言。Java 字节码需要由 Java 虚拟机(不是本机处理器)执行。使用 C 和 C++,代码被编译为本机处理器指令;无需解释。C 或 C++ 可执行文件与平台环境相关联,必须重新构建才能在另一个平台上运行。Java 更加独立于平台,可以在任何具有 Java 虚拟机 (JVM) 的平台上运行。

于 2013-07-14T20:39:37.400 回答