通过 JVM 日志来进行安全点分析

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介:

许多事件都可能会导致JVM暂停所有的应用线程。这类暂停又被称为”stop-the-world”(STW)暂停。触发STW暂停最常见的原因就是垃圾回收了(github中的一个例子),但不同的JIT活动(例子),偏向锁擦除(例子),特定的JVMTI操作,以及许多场景也可能会导致应用程序暂停。


应用程序线程可以被安全地停止掉的那个时间点,就叫做安全点。这一术语也通常用来指代SWT暂停。


通常来讲GC日志都是打开的。然而,并非所有安全点的信息都能完整地记录下来。想获取到完整的日志,可以使用下列的JVM选项:


-XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime


从参数名字来看你可能会觉得是与GC相关的,其实不然——打开这些选项能够记录下所有的安全点,而不止是GC暂停的。如果你用上述的选项来运行下这个例子(github源码)


你会在标准输出中看到如下信息:


Application time: 0.3440086 seconds

Total time for which application threads were stopped: 0.0620105 seconds

Application time: 0.2100691 seconds

Total time for which application threads were stopped: 0.0890223 seconds


很通俗易懂(和GC日志相比来说)——从中你可以得知应用程序在前344毫秒中是在处理实际工作的,然后将所有线程暂停了62毫秒,紧接着又工作了210ms,然后又暂停了89ms。


你还可以将这些选项与GC的选项结合起来使用,比如将上面这个程序加上-XX:+PrintGCDetails 选项后再运行一次,输出则变成这样了;


[Full GC (Ergonomics) [PSYoungGen: 1375253K->0K(1387008K)] [ParOldGen: 2796146K->2049K(1784832K)] 4171400K->2049K(3171840K), [Metaspace: 3134K->3134K(1056768K)], 0.0571841 secs] [Times: user=0.02 sys=0.04, real=0.06 secs]

Total time for which application threads were stopped: 0.0572646 seconds, Stopping threads took: 0.0000088 seconds


综上可知,应用线程被强制暂停了57ms来进行垃圾回收。其中又有8ms是用来等待所有的应用线程都到达安全点。如果我们用同样的选项运行另一个例子(Github源码)的话,输出又变成这样的了:


Total time for which application threads were stopped: 0.0001273 seconds, Stopping threads took: 0.0000196 seconds

Total time for which application threads were stopped: 0.0000648 seconds, Stopping threads took: 0.0000174 seconds


光从这些信息我们无从得知是什么导致的暂停,因为看不出有任何的垃圾回收的活动。如果你想更详细地了解安全点的信息的话,可以使用这组JVM参数:


-XX:+PrintSafepointStatistics -XX:PrintSafepointStatisticsCount=1


启用这些参数使得JVM会将一些额外的信息记录到标准输出中,大概类似这样:


5.141: RevokeBias [ 13 0 2 ] [ 0 0 0 0 0 ] 0

Total time for which application threads were stopped: 0.0000782 seconds, Stopping threads took: 0.0000269 seconds


关于安全点的信息是按照如下的顺序进行显示的:


  • JVM启动之后所经历的毫秒数(上例中是5.141)

  • 触发这次暂停的操作名(RevokeBias)。 如果你看见”no vm operation”,就说明这是一个”保证安全点”。JVM默认每秒会触发一次安全点来处理那些非紧急的排队的操作。GuaranteedSafepointInterval选项可以用来调整这一行为(设置为0的话就会禁用该功能)

  • 停在安全点的线程的数量(13)

  • 在安全点开始时仍在运行的线程的数量(0)

  • 虚拟机操作开始执行前仍处于阻塞状态的线程的数量(2)

  • 到达安全点时的各个阶段以及执行操作所花的时间(0)


因此我们可以看出,使用了偏向锁会导致大量的STW暂停,尽管它们只花了几十毫秒。在如今这个大量使用并发的年代,禁用它们也不是什么罕见的事情。


不管怎样,多打印些日志总会减少一些麻烦事的。你可以使用如下的JVM参数:


-XX:+LogVMOutput -XX:LogFile=vm.log


所有的虚拟机日志都会输出到vm.log文件中。










本文转自 小强测试帮 51CTO博客,原文链接:http://blog.51cto.com/xqtesting/1971579,如需转载请自行联系原作者
相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
1月前
|
SQL 监控 关系型数据库
使用 pt-query-digest 工具分析 MySQL 慢日志
【8月更文挑战第5天】使用 pt-query-digest 工具分析 MySQL 慢日志
33 3
使用 pt-query-digest 工具分析 MySQL 慢日志
|
25天前
|
存储 分布式计算 大数据
【Flume的大数据之旅】探索Flume如何成为大数据分析的得力助手,从日志收集到实时处理一网打尽!
【8月更文挑战第24天】Apache Flume是一款高效可靠的数据收集系统,专为Hadoop环境设计。它能在数据产生端与分析/存储端间搭建桥梁,适用于日志收集、数据集成、实时处理及数据备份等多种场景。通过监控不同来源的日志文件并将数据标准化后传输至Hadoop等平台,Flume支持了性能监控、数据分析等多种需求。此外,它还能与Apache Storm或Flink等实时处理框架集成,实现数据的即时分析。下面展示了一个简单的Flume配置示例,说明如何将日志数据导入HDFS进行存储。总之,Flume凭借其灵活性和强大的集成能力,在大数据处理流程中占据了重要地位。
33 3
|
26天前
|
应用服务中间件 Linux nginx
在Linux中,如何统计ip访问情况?分析 nginx 访问日志?如何找出访问页面数量在前十位的ip?
在Linux中,如何统计ip访问情况?分析 nginx 访问日志?如何找出访问页面数量在前十位的ip?
|
28天前
|
监控 安全 关系型数据库
在Linux中,什么是系统日志和应用程序日志?如何分析它们?
在Linux中,什么是系统日志和应用程序日志?如何分析它们?
|
1月前
|
存储 安全 Python
[python]使用标准库logging实现多进程安全的日志模块
[python]使用标准库logging实现多进程安全的日志模块
|
19天前
|
存储 消息中间件 监控
Java日志详解:日志级别,优先级、配置文件、常见日志管理系统ELK、日志收集分析
Java日志详解:日志级别,优先级、配置文件、常见日志管理系统、日志收集分析。日志级别从小到大的关系(优先级从低到高): ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF 低级别的会输出高级别的信息,高级别的不会输出低级别的信息
|
21天前
|
算法 关系型数据库 程序员
第一周算法设计与分析:A : log2(N)
这篇文章介绍了解决算法问题"输入一个数N,输出log2N(向下取整)"的三种编程思路,包括使用对数函数和幂函数的转换方法,以及避免浮点数精度问题的整数逼近方法。
|
2月前
|
算法 安全 Java
(七)JVM成神路之GC分代篇:分代GC器、CMS收集器及YoungGC、FullGC日志剖析
在《GC基础篇》中曾谈到过分代以及分区回收的概念,但基础篇更多的是建立在GC的一些算法理论上进行高谈阔论,而本篇则重点会对于分代收集器的实现进行全面详解,其中会涵盖串行收集器、并行收集器、三色标记、SATB算法、GC执行过程、并发标记、CMS收集器等知识,本篇则偏重于分析GC机制的落地实现,也就是垃圾收集器(Garbage Collector)。
|
2月前
|
消息中间件 Kubernetes Kafka
日志采集/分析
日志采集/分析
49 7
|
2月前
|
运维 监控 Java
(十)JVM成神路之线上故障排查、性能监控工具分析及各线上问题排错实战
经过前述九章的JVM知识学习后,咱们对于JVM的整体知识体系已经有了全面的认知。但前面的章节中,更多的是停留在理论上进行阐述,而本章节中则更多的会分析JVM的实战操作。