通过JVM日志来进行安全点分析
许多事件都可能会导致JVM暂停所有的应用线程。这类暂停又被称为”stop-the-world”(STW)暂停。触发STW暂停最常见的原因就是垃圾回收了(github中的一个例子),但不同的JIT活动(例子),偏向锁擦除(例子),特定的JVMTI操作,以及许多场景也可能会导致应用程序暂停。
应用程序线程可以被安全地停止掉的那个时间点,就叫做安全点。这一术语也通常用来指代SWT暂停。
通常来讲GC日志都是打开的。然而,并非所有安全点的信息都能完整地记录下来。想获取到完整的日志,可以使用下列的JVM选项:
1
|
-XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime |
从参数名字来看你可能会觉得是与GC相关的,其实不然——打开这些选项能够记录下所有的安全点,而不止是GC暂停的。如果你用上述的选项来运行下这个例子(github源码)
你会在标准输出中看到如下信息:
1
2
3
4
|
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 选项后再运行一次,输出则变成这样了;
1
2
|
[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源码)的话,输出又变成这样的了:
1
2
|
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参数:
1
|
-XX:+PrintSafepointStatistics -XX:PrintSafepointStatisticsCount= 1 |
启用这些参数使得JVM会将一些额外的信息记录到标准输出中,大概类似这样:
1
2
|
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参数:
1
|
-XX:+LogVMOutput -XX:LogFile=vm.log |
所有的虚拟机日志都会输出到vm.log文件中。如何解读这些日志并做出响应是一个很大的课题,这已经远超本文所讨论的范围了,不过未来我仍会更新一到两篇文章来讲下这个,请拭目以待.
通过JVM日志来进行安全点分析的更多相关文章
- JVM日志和参数的理解
写这篇wiki的目的:最近在调整Hbase的JVM,翻了些文档和wiki,想写点东西,给自己和想了解jvm日志和参数的同 学提供些帮助. 一:理解GC日志格式,读GC日志的方法 1:开启日志 -ver ...
- ZooKeeper日志与快照文件简单分析
有用过Zookeeper的都知道zoo.cfg配置文件中有dataDir配置项用于存储数据,不过可能有些人不太清楚这个目录具体存储的是那些数据,默认情况下这个目录是用于存储Log(事务日志)与Snap ...
- Android日志系统Logcat源代码简要分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6606957 在前面两篇文章Android日志系 ...
- Java 9 揭秘(19. 平台和JVM日志)
Tips 做一个终身学习的人. 在这章中,主要介绍以下内容: 新的平台日志(logging)API JVM日志的命令行选项 JDK 9已经对平台类(JDK类)和JVM组件的日志系统进行了大整. 有一个 ...
- java9新特性-18-统一的JVM日志系统
1.官方Feature 158: Unified JVM Logging 271: Unified GC Logging 2.使用说明 日志是解决问题的唯一有效途径:曾经很难知道导致JVM性能问题和导 ...
- JVM内存状况查看方法和分析工具
Java本身提供了多种丰富的方法和工具来帮助开发人员查看和分析GC及JVM内存的状况,同时开源界和商业界也有一些工具可用于查看.分析GC及JVM内存的状况.通过这些分析,可以排查程序中内存泄露的问题及 ...
- 【JVM.4】调优案例分析与实战
之前已经介绍过处理Java虚拟机内存问题的知识与工具,在处理实际项目的问题时,除了知识与工具外,经验同样是一个很重要的因素.本章会介绍一些具有代表性的案例. 本章的内容推荐还是原文全篇看完的好,实在不 ...
- 爆料喽!!!开源日志库Logger的剖析分析
导读 Logger类提供了多种方法来处理日志活动.上一篇介绍了开源日志库Logger的使用,今天我主要来分析Logger实现的原理. 库的整体架构图 详细剖析 我们从使用的角度来对Logger库抽茧剥 ...
- 用Kibana和logstash快速搭建实时日志查询、收集与分析系统
Logstash是一个完全开源的工具,他可以对你的日志进行收集.分析,并将其存储供以后使用(如,搜索),您可以使用它.说到搜索,logstash带有一个web界面,搜索和展示所有日志. kibana ...
随机推荐
- O003、准备 KVM 实验环境
参考https://www.cnblogs.com/CloudMan6/p/5240770.html KVM 是 OpenStack 使用的最广泛的Hypervisor,本节介绍如何搭建 KVM ...
- 01 Mysql数据库初识
一.数据库概述 1.什么是数据库? 什么是数据库呢? 先来看看百度怎么说的 数据库,简而言之可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增.截取.更新.删除等操作. 所谓“ ...
- C# 封装返回类
using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using System. ...
- redis一键部署脚本
1.新建一个名为 auto_install_redis.sh的文件 2.将下面脚本拷贝到文件中,具体步骤在注释里面 #环境 linux #一键安装redis,在linux环境中使用脚本运行该文件(sh ...
- linux命令详解——ftp
ftp服务器在网上较为常见,Linux ftp命令的功能是用命令的方式来控制在本地机和远程机之间传送文件,这里详细介绍Linux ftp命令的一些经常使用的命令,相信掌握了这些使用Linux 进行ft ...
- 三,k8s集群的应用入门
目录 kubernetes集群简单应用 kubectl常用命令: 创建pod service创建 测试其他pod通过series访问nginx 测试手动变更nginx对应的pod的ip pod和ser ...
- Linux驱动开发之字符设备驱动模型之file_operations
90%的驱动模型都是按照下图开发的 下面来说下设备描述结构是什么东西 打开Linux-2.6.32.2的Source Insight 工程,搜索cdev 比如一个应用程序需要调用read和write这 ...
- Summer training round2 #6 (Training #22)
A:二分答案 如果中位数比目前的大就right=mid-1 else left=mid+1 C!:几何 G:优先队列贪心 #include <bits/stdc++.h> using na ...
- highcharts的基本使用(转载)
1 概述 Highcharts是一个跨浏览器的JavaScript图表控件,支持柱状图.趋势图.面积图.饼图.环形图.组合图.堆积图.散点图. Highcharts图表的基本功能,只需要引入两个JS类 ...
- ES添加文档 踩坑之 —— The number of object passed must be even but was [1]
读取文件,获取json格式的数据doc, 然后使用 bulkRequestBuilder.add(client.prepareIndex(index, type, id).setSource(doc) ...