GC花了三个小时来降低1.2GB的堆,可能是什么原因?

2022-09-02 13:25:20

在我们的一台服务器中,垃圾回收花了将近三个小时才尝试(成功)降低(成功)1.2GB的堆内存。从 1.4GB 到 200MB。

在此期间,CPU使用率很高,几乎达到80-100%。可能的原因是什么?我们有4个具有相同配置(JVM设置,服务器配置,硬件,网络)的服务器,假设没有人对其进行任何更改,那么特定服务器运行3小时GC的原因是什么。

所有其他服务器对于每个GC活动仅花费5到10分钟。

请附上HP BAC的图表,方便您参考。显示我认为GC启动的时间,以及GC停止的时间。

enter image description here

(正如斯蒂芬所指出的,更确凿的发现)当服务器管理员回复我时,请提供以下信息:

  • 您正在使用的 JVM 的确切版本。(标准 Java SE 1.4.2)
  • JVM 选项。(即将推出)
  • Web 容器/服务器库的详细信息。(即将推出)
  • 有关服务功能的信息。来自服务器/服务日志文件的任何相关线索(即将推出)
  • 请求日志中的任何相关模式(即将推出)
  • GC 记录事件发生的时间。(如果当前未启用 GC 日志记录,则可能需要启用它并等待问题再次出现。(即将推出)

答案 1

这里没有太多的数据可以工作,但我的直觉是:你正在交换。我们唯一一次看到GC时间变高是当你过度使用盒子并且它正在分页到磁盘时。这可能会将事情变成一个数量级(或更多)的性能下降。

您需要收集操作系统(如果适用,则可能是虚拟机管理程序)交换统计信息以证明或反驳此理论。

(我知道CPU时间比我预期的交换时间要高,但你永远不会知道。

如果您发布硬件配置,“java -version”信息和JVM命令行参数(例如:-Xmx和-Xms),以帮助缩小您实际运行的范围,那也将很有帮助。


答案 2

您没有提供太多信息,但可能的原因可能是:

  • 应用程序中的错误;例如,具有一些相当特殊特征的内存泄漏,或者不断耗尽内存然后重新启动的任务。

  • 意外或故意拒绝服务攻击;例如,一些客户端不断重试一个超大的请求,其参数每次都会减少“问题大小”。

  • 具有某些特征的单个运行时间极长的请求。

  • 殴打 - 参见@Trent格雷 - 唐纳德的答案。(如果您有过度分配的内存,那么GC算法(涉及查看随机分散在大量页面上的大量对象)极有可能引起轰击。我只是不确定这是否会导致堆使用量像你所看到的那样逐渐下降。

  • JVM 设置的病理性组合。

  • 您正在使用的特定 JVM 中的垃圾回收器中的 bug。

  • 上述的一些组合。

这是需要获得Oracle / Java支持合同的问题。


以下信息可能有助于诊断此问题:

  • 您正在使用的 JVM 的确切版本。
  • JVM 选项。
  • Web 容器/服务器库的详细信息。
  • 有关服务功能的信息。
  • 来自服务器/服务日志文件的任何相关线索
  • 请求日志中的任何相关模式
  • GC 记录事件发生的时间。(如果当前未启用 GC 日志记录,则可能需要启用它并等待问题再次出现。