JVM 日志记录 - Sip of Java

VM 日志记录长期以来一直是 JDK 的一部分。它可以成为执行根本原因分析和找出性能怪癖的出色工具。在 JDK 9 中,对 VM 日志记录的处理方式进行了多项更改,使其更易于使用和配置。让我们在本文中了解如何在 VM 日志记录中使用它。

启用和配置日志记录

可以通过向 java 命令添加 -Xlog 在最基本级别启用 VM 日志记录。这将启用 VM 日志记录,其默认配置为

-Xlog:all=info:stdout:uptime,levels,tags

以上内容将为 info 级别下的所有不同类别启用 VM 日志记录。它将把 VM 日志打印到 stdout,包括 JVM 的正常运行时间、日志语句的级别以及与之关联的标签。下面是日志语句的一个示例

[1.043s][info][methodhandles           ] lookup_polymorphic_method => intrinsic {method} {0x000000010a38c880}

在大多数情况下,默认的 VM 日志记录会过于冗杂而无法使用。幸运的是,VM 日志记录可以配置为满足多种需求。

配置标签

启用 VM 日志记录时,开发人员通常会查看特定问题。VM 日志记录可以配置为仅生成与特定类别匹配的日志,例如:垃圾回收 (gc)、即时编译器 (jit)、CPU 使用率 (cpu) 等。将日志记录限制在特定类别可以帮助减少冗余,并允许你专注于关注的领域

-xlog:gc,heap

以上示例将日志输出限制为仅包含 gcheap 标签的日志语句。或者,可以使用以下示例打印出同时包含 gchead 的日志,并且可以添加 *,以便打印出包含 gcheap 标签的任何日志

-xlog:gc+heap
-xlog:gc*,heap*

标签可以设置为不同的日志记录级别;off, trace, debug, info, warning, error;例如,如果我想要 heapdebug 日志记录,但想要 gcerror 日志记录,它将如下所示

-Xlog:'gc*=error,heap*=debug'

配置输出位置

默认情况下,VM 日志记录将打印到 stdout;但是,这通常可能不是希望发送 VM 日志记录的位置;在许多情况下,最好将 VM 日志记录写入一个单独的文件,方法如下

-Xlog:'gc*,heap*':vm-logging.log

java 命令中拥有 -Xlog 的多个实例也是有效的,这对于根据类型将 VM 日志写入不同位置很有用。在以下示例中,gc 日志语句被写入 gc.log,而 heap 日志语句被写入 heap.log

-Xlog:'gc*':gc.log -Xlog:`heap*`:heap.log

减少性能开销

VM 日志记录可能会给 Java 应用程序造成大量的开销。为了解决这个问题,请考虑启用异步日志记录 -Xlog:async,它会将日志语句写入内存缓冲区,该缓冲区会定期刷新。缓冲区大小可以通过 -XX:AsyncLogBufferSize=<bytes> 进行配置。就像在这个示例中

-Xlog:'gc*=trace':gc-trace.log -Xlog:async -XX:AsyncLogBufferSize=102400

在正在运行的 JVM 上配置日志记录

可以使用 jcmdVM.log 在 JVM 上配置 VM 日志记录。使用 java 命令配置 VM 日志记录时可用的所有配置选项都可用,但通过 outputoutput_optionswhatdecorators 参数提供选项,就像在以下示例中

jcmd <pid> VM.log output="file=heap.log" output_options="filecount=5,filesize=10m" what="heap=info" decorators="time,level"

其他阅读材料

JEP 158:统一的 JVM 日志记录

JEP 271:统一的 GC 日志记录

使用 JVM 统一日志记录框架启用日志记录

使用 jcmd 配置日志记录示例

-Xlog:help 的打印输出

编码愉快!