14

我正在尝试分析我们应用程序的 GC 行为(在Tomcat中运行,在Sun 的 Hotspots下,JVM 1.6下)。

到目前为止,我已经指示 JVM 将 GC 日志发送到一个单独的文件,使用...

-Xloggc:gc.log 
-XX:+PrintGCApplicationStoppedTime 
-XX:+PrintGCApplicationConcurrentTime 
-XX:+PrintGC 
-XX:+PrintGCTimeStamps 
-XX:+PrintGCDetails

...并使用 jstat 输出日志...

jstat -gc -t 29045 5s > jstat.gc

我看到了有趣的信息,但没有找到帮助我分析/可视化这些日志的工具。我被这个问题指向 GCViewer ,但它只解析 gc.log 中的几行日志,然后崩溃并出现异常。对于我正在使用的特定 JVM,是否有更好或更最新的工具来解析这些特定日志?

4

7 回答 7

6

gcviewer多年来没有更新,所以它时好时坏 - 一些 gc 文件可以正常工作,其他文件会出现异常。

IBM 的 gc 日志解析器可以正常工作, http://www.alphaworks.ibm.com/tech/pmat/faq

Sun 有一个叫做 GCPortal 的东西,但它需要:

  • 安装到 Web 应用服务器
  • 安装 awk 和 perl
  • 使用 JDBC 驱动程序和配置安装 RDBMS
  • 真正的杀手,第三方图形/图表软件曾经是免费的,现在不是。惊人。

gchisto已经死了,项目中不再有任何东西。

HPJmeter 不理解 IBM gc 文件。

于 2010-07-16T20:17:16.660 回答
3

IBM Support Assistant中可用的工具做得很好。

于 2011-03-30T16:47:56.250 回答
3

我个人使用HP JMeter进行大量 GC 可视化。它在 SUN JRE 上运行“正常”,在 HP 的 JRE 上运行良好(如图)。

对于 Sun HotSpot 1.6(在非 HP 平台上),我使用这些 GC 选项来生成用于分析的日志:

-Xloggc:/path/to/vgc/log/location/logfile.vgc  --XX:+PrintHeapAtGC 
于 2009-12-03T16:28:42.753 回答
2

你看过jvisualvm吗?附带最新的 JDK,并允许您观看 JVM。示例输出(使用visualGC插件)。示例输出 -替代文本 http://g4u0420c.houston.hp.com/en/5992-4687/img/visualgc_2.png

于 2009-12-03T17:13:42.870 回答
0

我尝试使用 Visual GC,但它似乎适用于 id 进程(jvm one ou jstatd one)。我不能将它与 jstat.gc 一起使用,我的意思是文件而不是流,对吗?

于 2009-12-23T22:40:53.057 回答
0

尝试使用 gchisto (gchisto.dev.java.net)。它可以理解 GC 日志输出(我不确定它是否已更新为与 G1 GC 一起使用)。您必须从 CVS 获取源代码(为此您需要一个 dev.java.net 帐户)并自己构建它

于 2010-03-04T07:46:36.540 回答
0

这是一个 0.00 美元的日志抓取工具,适用于 1.5 CMS 收集器,它为您提供 GC 暂停的高级视图。

您可能需要将位置参数 $7 参数更改为时间戳函数以匹配您的日志行语法(我的 .out 被 Tanuki Wrapper “增强”)。

#! /usr/bin/awk -f
# Awk script to parse .out logs and print total of
# stop-the-world GC pause times in ten minute intervals

BEGIN {print "t\timark\tmark\tremark\tfullgc"}

/CMS-initial-mark:/ {
  t=timestamp($7);
  imark[t] += $(NF-1);
}

/\[CMS-concurrent-mark:/ {
  t=timestamp($7);
  split($(NF-1), b, "/");
#  print t" NF="NF" val="b[1];
  mark[t] += b[1];
}

/CMS-remark/ {
  t=timestamp($7);
  remark[t] += $(NF-1);
}

/\[Full GC / {
  t=timestamp($7);
  level=0;
  for (i=1; i<=NF; i++) {
      if ($i ~ /\[/) {
        level++;
      } else if ($i ~ /\]/) {
        level--;
      }
  }
  while (level > 0) {
    getline;
    for (i=1; i<=NF; i++) {
      if ($i ~ /\[/) {
        level++;
      } else if ( $i ~ /\]/ ) {
        level-- ;
      }
    }
  }
  if ( $(NF) ~ /secs\]/ ) {
    full[t] += $(NF-1) ;
  }
}

function timestamp(str) {
  split(str, a, ":");
  return a[1]":"substr(a[2],0,length(a[2])-1)"0";
}

# print out UK+US trading hours

END {
  for (hour = 5; hour <= 16; hour++) {
    for (minute = 0; minute <= 59; minute+=10) {
      t = sprintf("%02d:%02d", hour, minute);
      printf "%s\t%d\t%d\t%d\t%d\n", t, imark[t], mark[t], remark[t], full[t];
    }
  }
}
于 2010-06-11T20:54:10.950 回答