【问题标题】:Jstat and Jvisualvm show different numbers for heap usage/allocationJstat 和 Jvisualvm 显示不同的堆使用/分配数字
【发布时间】:2015-03-10 19:35:23
【问题描述】:

我无法在服务器上运行任何基于 GUI 的分析器(例如 jvisualvm)来监控正在运行的 Java 进程的堆。根据this answer,我可以使用jstat -gc <pid>查看OU和OC列,了解堆使用情况和分配情况。

但我只是在另一台服务器上比较了 jvisualvm 和 jstat,它们显示的堆使用和分配数字并不相同。

Jvisualvm 显示一个 Java 进程有大约 1GB 分配给堆,其中大约 500MB 被使用:

但是对于同一个进程,jstat 在 OC 列下仅显示约 700MB,在 OU 列下仅显示约 226MB:

# jstat -gc 39621
S0C    S1C    S0U    S1U      EC       EU        OC         OU       PC     PU    YGC     YGCT    FGC    FGCT     GCT
16384.0 17920.0 3984.0  0.0   322560.0 10320.4   699392.0   226295.2  83968.0 47921.1  11966   66.103  12      3.083   69.186

为什么 jvisualvm 和 jstat 显示不同的堆使用和分配数字?

【问题讨论】:

    标签: java profiling heap-memory


    【解决方案1】:

    通过 jstat 查看当前保留堆大小的简单 unix 命令:(它与 jconsole 编号匹配)

    jstat -gc <pid> 3000 | awk '{split($0,a," "); print a[3]+a[4]+a[6]+a[8]}'
    

    【讨论】:

      【解决方案2】:

      对于 Java 8,jstat 实用程序已更新,对于

      jstat –gc <PID>
      

      在输出中有这些字段:

      S0C     S1C      S0U   S1U     EC       EU        OC         OU        MC      MU      CCSC   CCSU    YGC     YGCT    FGC     FGCT     GCT   
      
      39936.0 29184.0  0.0   29035.4 273920.0 170661.5  699392.0   39235.9   98480.0 97022.7 8624.0 8163.3     63    0.925  38      2.363    3.289
      

      堆使用率

      要获取当前堆使用情况,大概是jVisualJM中的值,需要加上以下值:

      S0U: Survivor space 0 utilization (kB)
      
      S1U: Survivor space 1 utilization (kB)
      
      EU: Eden space utilization (kB)
      
      OU: Old space utilization (kB)
      

      看着Java 8 Virtual Machine Garbage Collection Tuning Guide, 似乎堆由“年轻”一代(Eden & Survivor 0 & 1 空间)和“老”一代(旧空间)组成。

      元空间使用

      要获取当前的元空间使用情况,大约是jVisualJM中的值,需要如下大小:

      MU: Metaspace utilization (kB)
      

      备注

      无论出于何种原因,我从未能够在 jstat 和 jVisualJM 之间获得完全相同的值,但足够接近,可以放心地使用这两个工具。

      JVM 内存池

      有关 JVM 内存池的更多详细信息,请参阅涵盖 Java 7 和 8 的 StackOverflow question & answer。

      Java 8 Using JConsole guide 中也有一些信息,但令人惊讶的是,这仍然提到 Java 7 永久代空间而不是 Java 8 元空间。

      【讨论】:

        【解决方案3】:

        事实证明,将 jstat 的 EU 和 OU 列相加大约等于 jvisualvm 中显示的堆使用量。对于我正在监视的进程,EU+OU 总是比 jvisualvm 中显示的值小 12 MB。 (在我在问题中提供的示例中,jvisualvm 显示 506 MB 的堆使用量,而 jstat 显示 EU+OU = 240 MB。所以我必须在堆使用量回落到 250 MB 后立即运行 jstat。)

        jstat 的 EC 和 OC 列相加大约等于 jvisualvm 中显示的堆分配。对于我正在监视的进程,EC+OC 比 jvisualvm 中显示的大约少 45-60 MB。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-11-05
          • 1970-01-01
          • 2017-01-29
          • 2017-04-11
          • 2017-09-29
          • 1970-01-01
          • 2012-06-05
          • 1970-01-01
          相关资源
          最近更新 更多