Java GC花费了三个小时来减少1.2GB的堆,原因是什么?

Java GC花费了三个小时来减少1.2GB的堆,原因是什么?,java,garbage-collection,jvm,Java,Garbage Collection,Jvm,在我们的一台服务器上,垃圾收集花了将近三个小时试图(成功)减少1.2GB的堆内存。从1.4GB到200MB 在此期间,CPU使用率很高,几乎为80-100%。原因可能是什么?我们有4台这样的服务器具有相同的配置(JVM设置、服务器配置、硬件、网络),假设没有人对其进行任何更改,那么特定服务器运行3小时GC的原因可能是什么 所有其他服务器每次GC活动只需要5到10分钟 请附上HP BAC的图表,以供参考。显示我认为GC启动的时间以及GC停止的时间 (正如Stephen指出的,以获得更多结论性发现

在我们的一台服务器上,垃圾收集花了将近三个小时试图(成功)减少1.2GB的堆内存。从1.4GB到200MB

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

所有其他服务器每次GC活动只需要5到10分钟

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

(正如Stephen指出的,以获得更多结论性发现)在服务器管理员回复我时提供以下信息:

  • 您所使用的JVM的确切版本 使用(标准Java SE 1.4.2)
  • JVM选项(即将推出)
  • 详情 web容器/服务器库(即将推出)
  • 关于服务内容的信息 做警方有没有相关线索 服务器/服务日志文件(即将推出)
  • 请求日志中的任何相关模式(即将发布)
  • 发生故障时的GC日志 事件(如果您当前没有 已启用GC日志记录,您可能需要 启用它并等待问题解决 递归。)(即将到来)

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

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

      • 意外或故意的拒绝服务攻击;e、 g.一些客户机不断重试一个过大的请求,每次都使用减少“问题大小”的参数

      • 具有特定特征的单个长时间运行的请求

      • 痛击-参见@Trent Gray Donald的回答。(如果内存分配过度,那么GC算法(涉及查看随机分布在多个页面上的多个对象)很可能引发抖动。我只是不确定这是否会导致堆使用率逐渐下降,就像您看到的那样。)

      • JVM设置的病态组合

      • 您正在使用的特定JVM中的垃圾收集器中存在错误

      • 以上的一些组合

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


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

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

        • 这里没有太多数据可供处理,但我的直觉是:你在交换数据。我们唯一一次看到GC时间达到这么高的时候是当您过度使用了这个框,并且它正在分页到磁盘。这会使性能下降一个数量级(或更多)

          您需要收集操作系统(以及可能的虚拟机监控程序(如果适用))交换统计数据来证明或反驳这一理论

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


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

          我想他们说动态内存分配的时间是无限的,这不是开玩笑吧。。。(顺便问一下,BAC代表什么?我有点困惑,以为它代表的是无关的东西,哈哈。)嗨,Mehrdad,我想它代表的是商业活动中心。嗨,Mehrdad,你说的“动态内存分配是无限的”是什么意思,你指的是释放吗?由于GC扫描。。谢谢。@Chin:哈哈,好的。:)不,我指的是分配(虽然它也适用于解除分配),因为最终触发解除分配的通常是分配。@Chin:这只是部分版本信息。完整版本信息包括修补程序编号、操作系统平台以及是32位还是64位。(尽管我认为Java 1.4.2只能是32位。)嗨,格雷,谢谢你的评论,我将在稍后发布硬件配置(可能是几天到一周,我需要与服务器团队联系以获取这些数据)。但是,当您前面提到交换时,您是指内存和磁盘之间的页面交换吗?为什么JVM会出现这种情况JVM是否可以将未使用的对象钝化到磁盘中,然后再进行交换?正确,是的,我的意思是将内存页交换到磁盘或从磁盘页交换内存。出现这种情况的原因有几个:您的机器内存过度使用,-Xmx对于机器来说太大了,您有一个本机内存泄漏,等等。操作系统应该有比分配给JVM堆(-Xmx)更多的RAM。+1-良好的理论。在Unix/Linux上,当您运行
          vmstat 5
          等时,这将显示为高交换率。