垃圾回收是否不利于此类程序的性能

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

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


答案 1

不,您的担忧很可能是没有根据的。

当处理大型堆和破碎的内存(需要停止世界集合)或中等生活对象时,GC可能是一个问题,这些对象被提升到旧一代,但随后迅速取消引用(需要过多的GC,但可以通过调整new:old空间的大小比例来修复)。

网络爬虫不太可能适合上述两个配置文件中的任何一个 - 您可能不需要大量的老一代,并且应该有相对较短的对象(解析数据时内存中的页面表示),这将在年轻一代收集器中得到有效处理。

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

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


答案 2

程序员C++GC的典型担忧是延迟。也就是说,当您运行程序时,周期性 GC 会中断突变体并导致延迟峰值。当我以运行 Java Web 应用程序为生时,我有几个客户会在日志中看到延迟峰值并抱怨它 - 我的工作是调整 GC 以尽量减少这些峰值的影响。多年来,GC取得了一些相对复杂的进展,使可怕的Java应用程序以持续的低延迟运行,Sun(现在的Oracle)工程师的工作给我留下了深刻的印象,他们使这成为可能。

但是,GC 一直非常擅长处理具有高吞吐量的任务,其中延迟不是问题。这包括 cron 作业。您的工程师有毫无根据的担忧。

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

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