垃圾收集是否对这类程序的性能有害

时间:2011-09-23 23:07:55

标签: java c++ memory-management garbage-collection

我正在构建一个可以通过cron作业定期调用AWS EC2实例(可能)的程序。该程序将“抓取”/“轮询”我们与之合作的特定网站,并将其内容编入索引/汇总并更新我们的数据库。我认为java非常适合用于编写这个应用程序的语言。我们工程团队的一些成员担心java垃圾收集功能的性能损失,并建议使用C ++。

这些有效的顾虑吗?这是一个可以通过cron作业每30分钟调用一次的应用程序,只要它在该时间范围内完成任务,我认为性能是可以接受的。我不确定垃圾收集是否会成为性能问题,因为我认为服务器将拥有足够的内存,并且实际跟踪有多少对象指向内存区域,然后在达到0时声明内存空闲对我来说似乎并不太有害。

5 个答案:

答案 0 :(得分:11)

不,你的担忧很可能毫无根据。

在处理大堆时,GC可能是一个问题。破碎的内存(需要停止世界集合)或中等生命的对象,这些对象被提升为老一代,但随后很快被解除引用(需要过多的GC,但可以通过调整新旧空间的比例来修复)。

网络抓取工具不太可能适合上述两个配置文件中的任何一个 - 您可能不需要庞大的旧代,并且应该拥有相对较短的对象(在解析数据时内存中的页面表示),这将是有效地处理了年轻一代收藏家。

我们有一个内部爬虫(Java),可以在商用硬件(2G RAM)上每天愉快地处理200万页,包括每页额外的后处理,主要限制是带宽。 GC不是问题。

正如其他人所提到的,GC很少是吞吐量敏感应用程序(例如爬虫)的问题,但它可以(如果不小心)成为延迟敏感应用程序(例如交易平台)的问题。

答案 1 :(得分:11)

C ++程序员对GC的典型关注点是延迟。也就是说,当您运行程序时,周期性GCs会中断mutator并导致延迟峰值。回到以前,我曾经以Java Web应用程序为生,我有几个客户会看到日志中的延迟峰值并抱怨它 - 我的工作是调整GC以最大限度地减少这些峰值的影响。多年来,GC的一些相对复杂的进步使得怪异的Java应用程序以一致的低延迟运行,并且我对Sun(现在的Oracle)的工程师的工作印象深刻,他们使这成为可能。

但是,GC始终非常擅长处理高吞吐量的任务,而延迟并不是一个问题。这包括cron工作。你的工程师毫无根据的担忧。

  

注意:一个简单的实验GC将内存分配/释放的成本平均降低到少于两个指令,这提高了吞吐量,但这种设计相当深奥,需要大量内存,而EC2上没有这些内存

最简单的GC提供了大堆(高延迟,高吞吐量)和小堆(低延迟,低吞吐量)之间的权衡。需要进行一些分析才能使其适合特定的应用程序和工作负载,但这些简单的GC在大型堆/高吞吐量/高延迟配置中非常宽容。

答案 2 :(得分:7)

获取和解析网站将比垃圾收集器花费更多时间,其影响可能是不可理解的。此外,自动内存管理在处理大量小对象(如字符串)时通常比通过new / delete进行手动内存管理更有效。没有谈论垃圾收集内存更容易使用的事实。

答案 3 :(得分:5)

我没有任何硬数据支持这一点,但是执行大量小字符串操作的代码(在很短的时间内进行大量小分配和解除分配)应该快得多在垃圾收集环境中。

原因是现代GC通过将对象从“eden”空间移动到幸存者空间然后移动到终身对象堆来定期“重新打包”堆,并且现代GC针对案例进行了大量优化分配了许多小对象然后快速解除分配的地方。

例如,在Java中构建一个新字符串(在任何现代JVM上)与C ++中的堆栈分配一样快 。相比之下,除非你在C ++中使用花哨的字符串池,否则你的分配器会因为大量小而快速的分配而变得非常繁重。

此外,还有其他几个很好的理由可以考虑将Java用于此类应用:它对网络协议提供了更好的开箱即用支持,这是您获取网站数据所需要的,而且它还有更多能够抵御面对恶意内容时缓冲区溢出的可能性。

答案 4 :(得分:5)

垃圾收集(GC)基本上是一个时空权衡。您拥有的内存越多,您的程序执行垃圾收集所需的时间就越少。只要相对于最大实时大小(使用的总内存),您有大量可用内存,GC的主要性能 - 整堆集合 - 应该是罕见的事件。 Java的其他优势(特别是健壮性,安全性,可移植性和出色的网络库)使这一点变得简单。

要与您的同事共享一些硬数据,以显示GC与具有大量可用内存的malloc / free一样好,请参阅:

Quantifying the Performance of Garbage Collection vs. Explicit Memory Management ”,Matthew Hertz和Emery D. Berger,OOPSLA 2005。

  

本文提供了一个古老问题的经验答案:是   垃圾收集更快/更慢/与malloc / free相同的速度?我们   介绍oracular内存管理,一种让我们测量的方法   不加改变的Java程序,好像他们使用malloc和free一样。结果:a   好的GC可以匹配好的分配器的性能,但需要5倍   更多的空间。但是,如果物理内存很紧,常规垃圾   收藏家遭受了数量级的性能损失。

论文:PDF 演示幻灯片:PPTPDF