繁体   English   中英

Java垃圾收集导致延迟影响性能

[英]Java Garbage Collection Induced Latency affecting Performance

我注意到我的应用程序中出现了一个奇怪的现象。 我将对象提交到服务器后将其存储在Hashmap中,并在响应到达时将其删除。

我最近注意到跑步后性能非常慢。 检查后,我发现内存使用率保持在4GB,然后下降到小于1 GB。 我怀疑它正在清理很多对象,这就是性能变得如此糟糕的原因。

所以问题是为什么Java收垃圾收集这么晚? 也就是说,为什么要等到堆满了然后再进行垃圾收集呢? 不应该定期收集垃圾。

存储在HashMap中的对象就是在那个时候创建​​的,也就是说它们并不长久。

这是在Linux(RHEL),Oracle JVM HotSpot 7. 64位上。 4核心。 这就是应用程序的运行方式:

java -jar -Xmx4g prog.jar

注意:我已经看到了这一点: 调整垃圾收集以获得低延迟但是现在我想了解为什么GC需要这么长时间才能启动?

听起来你有两个问题之一:

  1. 如果你有半长寿命的物体,他们将从年轻一代转移到更老的一代(就像在HotSpot上移动到Mark-Compact一代 。)也就是说,他们将停止被引用计入收集并开始被保留为更慢GC。
  2. 您的年轻代堆空间对于您的使用模式而言太小,迫使对象从年轻一代移动到老一代。

我想看看你的年轻一代是否更大。 请参阅分代垃圾收集并查看各种类型的世代。

所以问题是为什么Java收垃圾收集这么晚? 也就是说,为什么要等到堆满了然后再进行垃圾收集呢? 不应该定期收集垃圾。

您正在使用“吞吐量”垃圾收集器,这就是收集器的行为方式。 它旨在通过最小化执行垃圾收集所花费的CPU时间百分比来最大化系统吞吐量。 它通过等待堆(或更确切地说,新对象空间)已满的简单策略来实现。 在所有条件相同的情况下,最有效的是:

  • 当你有很多垃圾时收集垃圾,并且
  • 垃圾收集时停止其他一切。

(要了解原因,您需要了解复制收藏家的工作方式的技术细节......)

当然,这意味着你会有重大的停顿。

如果您想要低延迟,则需要使用其他收集器。 但是,这会导致更大比例的实际CPU时间用于垃圾收集......以及其他与GC相关的开销。


如果你有很多重要的暂停,那么空间的相对大小也可能存在问题。 但是在你弄清楚相关参数之前,建议你打开GC日志,试图找出导致暂停的原因和频率。

这只是因为除非堆已满,否则默认GC不会启动。

JVM选择的默认垃圾收集器是Parallel GC。 它的目标是在尽可能短的停止世界暂停期间释放尽可能多的内存。 除非伊甸园已满,否则它不会在年轻一代开始。 同样,除非Tenured已满,否则它不会在老一代开始。

如果要定期清理内存,可以切换到CMS。 只需使用标志-XX:+UseConcMarkSweepGC 但是,这将意味着您的应用程序的一些开销。 这是让GC定期运行而不暂停应用程序的成本。

所以,总结一下:

  • 并行GC暂停应用程序,仅在没有其他选择时启动

  • CMS同时运行而不会暂停您的应用程序,但有一些开销

资料来源: http//www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM