技术标签: jvm
本文会记录一些本人用到的一些java排错或观察各项性能指标的工具,如jstack jmap greys jps jstat等,不断完善中。
看进程的所有配置参数、启动参数等
jinfo pid
jstack可以看JVM栈的一些日志,可以统计运行线程数、查看指定线程号的栈信息等。
具体来说,jstack可被用于生成JVM线程快照,一般称为thread dump
或javacore
文件,线程快照就是当前JVM内每一个线程正在执行的方法堆栈的集合,主要用来定位线程出现长时间停顿的原因,如死锁、死循环、请求外部资源长时间等待等。
用ps找到目标进程号,当然也可以通过top pid
来找资源最多的进程。
$ ps aux | grep name
$ ps aux | grep slave
root 23556 0.0 0.0 103236 868 pts/0 S+ 20:59 0:00 grep slave
root 29793 6.9 18.0 6721828 1430008 ? Sl 2018 9054:36 /usr/local/jdk1.8.0_77/bin/java
可见,目标进程号为 29793
找到消耗CPU最多的线程号
$ top -Hp 29793
top - 21:02:18 up 106 days, 6:46, 1 user, load average: 0.00, 0.00, 0.00
Tasks: 860 total, 0 running, 860 sleeping, 0 stopped, 0 zombie
Cpu(s): 2.4%us, 1.0%sy, 0.0%ni, 95.7%id, 0.4%wa, 0.0%hi, 0.5%si, 0.0%st
Mem: 7928044k total, 7154288k used, 773756k free, 268028k buffers
Swap: 8060920k total, 533128k used, 7527792k free, 3544100k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
29930 root 20 0 6564m 1.4g 6908 S 65.3 18.0 87:13.91 java
19455 root 20 0 6564m 1.4g 6908 S 0.3 18.0 3:26.83 java
19496 root 20 0 6564m 1.4g 6908 S 0.3 18.0 2:55.17 java
可见,上述进程中CPU利用率比较高的线程号为29930。
也可以使用如下命令:
ps -mp 2633 -o THREAD,tid,time | sort -rn
ps p 3036 -L -o pcpu,pid,tid,time,tname,cmd
线程号十进制转十六进制
$ printf "%x\n" 29930
74ea
jstack查看消耗CPU的信息:
jstack 进程号 |grep 16进制线程号
$ jstack 29793 |grep 74ea
"metrics-meter-tick-thread-2" #86 daemon prio=5 os_prio=0 tid=0x00007f7d480b6000 nid=0x74ea waiting on condition [0x00007f7cff5ef000]
结果说明:
也可以使用以下命令看该线程后指定行数的堆栈信息
jstack -l 进程号 | grep -A 20 16进制线程号
$ jstack -l 29793 | grep -A 20 74ea
可以把结果输出到某个文件,然后在结果里面找刚才16进制线程号关键字
十六进制转10进制
echo "5C3"|awk '{printf("%d\n",strtonum("0x"$1))}'
还可参考:
jmap -dump:format=b,file=fileName PID
进行dump保存堆现场grep 'java.lang.Thread.State' jstack.log | wc -l
来计算线程数grep -A 1 'java.lang.Thread.State' jstack.log | grep -v 'java.lang.Thread.State' | sort | uniq -c |sort -n
查看有无异常日志greys
是一款Java在线问题诊断工具,主页greys-anatomy
curl -sLk http://ompc.oss.aliyuncs.com/greys/install.sh|bash
命令将会下载的启动脚本文件greys.sh到当前目录,你可以放在任何地方或加入到$PATH中
查看指定类的指定方法传入的参数情况,还可以加入任意字符串便于看懂输出:
watch -b com.chengc.test.Statistics testmethod "'<user_id,'+params[0]+'>'+'__<user_name,'+params[1]+'>'+'__<age,'+params[2]+'>'+'__<country,'+params[3]+'>'"
jmap可方便的查看jvm 堆统计、对象统计、dump等
# 连接运行中的进程
jmap [option] <pid>
# to connect to a core file
jmap [option] <executable <core>
# 连接远程调试服务器
jmap [option] [server_id@]<remote server IP or hostname>
上面选项:
上述的[option]
有以下选项:
<none> to print same info as Solaris pmap
-heap 打印java heap统计信息
-histo[:live] 打印java对象统计信息; 如果`:live`加了,就只统计存活对象
-clstats 打印classloader统计信息
-finalizerinfo 打印等待finalization的对象信息
-dump:<dump-options> 生成java heap dump文件
dump-options:
live dump only live objects; if not specified,
all objects in the heap are dumped.
format=b binary format
file=<file> dump heap to <file>
Example: jmap -dump:live,format=b,file=heap.bin <pid>
-F force. Use with -dump:<dump-options> <pid> or -histo
to force a heap dump or histogram when <pid> does not
respond. The "live" suboption is not supported
in this mode.
-h | -help to print this help message
-J<flag> to pass <flag> directly to the runtime system
在逃逸分析时,可以使用jmap辅助查看逃逸分析的执行效果:
jmap -histo:live pid
以上结果说明:
符号 | 含义 |
---|---|
B | byte |
C | char |
D | double |
F | float |
I | int |
J | long |
Z | boolean |
[ | 基本类型数组,如[I表示int[] |
[L+类名 | 自定义类数组 |
[类名 | 自定义类对象 |
具体可见Java-JVM-逃逸分析 |
可以使用以下命令对java进程进行dump操作:
jmap -dump:format=b,live,file=fileName PID
例如,我们这里对idea的进程的存活对象进行dump:
jmap -dump:format=b,live,file=jmap_idea_dump.tmp 34208
这样,在执行命令的目录下就生成了jmap_idea_dump.tmp
。
可在http://www.eclipse.org/mat/downloads.php下载
分析可参考:
mac版本
MemoryAnalyzer-1.8.1.20180910-macosx.cocoa.x86_64.zip
,解压后是一个可运行app,双击后可执行运行,界面化分析。
linux版本
MemoryAnalyzer-1.9.1.20190826-linux.gtk.x86_64.zip,解压后是一个文件夹
可以看到 深色部分的内存被怀疑内存泄露。下面的Problem Suspect1
就是问题怀疑的描述,说io.netty.buffer.PoolChunk
占用了81.36%
Shallow Size
和Retained Size
Shallow Size
是对象本身占据的内存的大小,不包含其他引用的其他对象。对于常规对象(非数组)的Shallow Size
由其成员变量的数量和类型来定。
数组的ShallowSize由数组类型和数组长度来决定,它为数组元素大小的总和。
Retained Size
对象本身加上可直接或间接引用(A->B->C,C就是A的间接引用)到的对象的大小,然后减去被GC Roots存在另外一条路径引用的对象,也就是说是该对象自己引用但并没有被GC Roots直接或间接引用的路径(这个路径不包含目标对象)。
所以这也可以理解为GC之后所能回收到内存的总和,因为回收目标对象也能回收这种类型的引用对象。
更多可看这两篇译文:
https://www.yourkit.com/docs/java/help/sizes.jsp 或这篇译文 http://blog.csdn.net/kingzone_2008/article/details/9083327 讲的很详细
Retained为一次FullGC后的还存活的大小
首先说下Dominator和持有的区别:
关于Dominator Tree的概念以下这篇文章会讲的很详细支配树(Dominator Tree)
引用树(右)和支配树(左)关系如下:
对象A和B由根对象直接支配,由于在到对象C的路径中,可以经过A,也可以经过B,因此对象C的直接支配者也是根对象。
下面看看MAT中的dominator_tree
Dominator Tree,中文翻译为支配(对象)树?所以点击每一行左边的箭头会列举出这个对象所支配的所有对象。
注意是支配(对象),而不是用持有(对象)树。
前面展示的每一行都能点右键,然后选择 List Object
:
Path To GC Roots
是针对Dominator Tree表格的,在任一行上点右键可看到该菜单项。在Histogram里只有Merge shortest Path To GC Roots,意思是会找出最短的路径。
Path To GC Roots人如其名,意为显示出GC Roots到这个对象的所有路径。一般用exclude all phantom/weak/soft etc. references
这个排除虚、弱、软引用的这个选项。因为这几种情况堆内存GC都可以回收的到,不是造成内存泄漏的原因。唯有强引用指向的对象GC回收不了。选中后出现如下图表格:
这图很直白。DemoActivity对象 ←(被持有) MySingleton对象的mContext引用 ←(被持有) MySingleton对象的instance引用(因为是静态变量,GC不会回收)。
可以看java应用heap配置的分配情况以及使用情况。
jmap -heap 35132
图形化的JVM分析工具。安装jdk后自带,比如我的mac下jconsole位于
/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/bin/jconsole
命令行终端直接敲jconsole
进入jconsole:
这里我们选择一个本地idea进程,然后点连接,进入界面:
jps 命令可查看 Java 进程的启动类、传入参数和 Java 虚拟机参数等信息。
$ jps -help
usage: jps [-help]
jps [-q] [-mlvV] [<hostid>]
Definitions:
<hostid>: <hostname>[:<port>]
jstat [-options] pid interval
options如下:
使用-gccause
时,LGCC表示上次gc的原因,GCC表示此次gc的原因。注意:当使用CMS作为老年代收集器的时候,每执行一次Old GC,FGC就会增加两次。
使用jstat java gc情况
jstat -gcutil pid 间隔时间(毫秒)
名称 | 含义 |
---|---|
S0 | 年轻代幸存者0区使用百分比 |
S1 | 年轻代幸存者1区使用百分比 |
E | 年轻代Eden区使用百分比 |
O | 老年代使用百分比 |
M | 元空间使用百分比 |
CCS | CompressedClassSpaceSize使用百分比 |
YGC | 从应用程序启动到当前采样时,YoungGC次数 |
YGCT | 从应用程序启动到采样时YongGC总耗时(s) |
FGC | 从应用程序启动到当前采样时,FullGC次数 |
FGCT | 从应用程序启动到采样时FullGC总耗时(s) |
GCT | 从应用程序启动到采样时GC总耗时 |
jstat -gc pid 间隔时间(毫秒)
以上数据单位为KB。可以配合使用jmap进行查看:
jhat为jdk自带,可以配合jmap分析其dump出的文件,且以html方式输出结果,包括对象的数量,大小等等,并支持对象查询语言OQL。
jmap -dump:format=b,file=dumpFileName pid
$ jmap -dump:format=b,file=/Users/chengc/cc/dumptest.dat 41005
Dumping heap to /Users/chengc/cc/dumptest.dat ...
Heap dump file created
$ jhat /Users/chengc/cc/dumptest.dat
Reading from /Users/chengc/cc/dumptest.dat...
Dump file created Sat Feb 16 17:59:22 CST 2019
Snapshot read, resolving...
Resolving 89501 objects...
Chasing references, expect 17 dots.................
Eliminating duplicate references.................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
如果目标dump文件太大,可以加以下参数限制内存:
-J<flag> Pass <flag> directly to the runtime system. For
example, -J-mx512m to use a maximum heap size of 512MB
需要收费。wat
JProfiler是由ej-technologies GmbH公司开发的一款性能瓶颈分析工具(该公司还开发部署工具),专用于分析J2SE和J2EE应用。JProfiler的GUI可以更方便地找到性能瓶颈、抓住内存泄漏(memory leaks),并解决多线程的问题,例如分析哪个对象占用的内存比较多、哪个方法占用较大的CPU资源等。可使用Jprofiler来监控Spark应用在local模式下运行时的性能瓶颈和内存泄漏情况。
其特点:
Intellij IDEA集成JProfiler性能分析神器
javap是JDK自带的反汇编器,可以查看java编译器为我们生成的字节码指令,并且贴心的附上了注释。
用法很简单,只需要对编译后的TestClass.class
文件输入以下命令:
javap -c TestClass
具体可以参考例子javap的基本用法
可参考
本地命令行直接通过JVisualVM
就可启动。
可观察Java程序资源使用情况,可方便地进行堆/内存 dump等。
VisualVmM是强大的运行监视和故障处理数据,他不需要被监视的目标程序基于特殊的agent运行,因此它对应用程序地实际性能影响很小,使得它可以直接应用到生产环境中。它上面有许多好玩的插件,比如Btrace,它可是线上调试的神奇,可以在不停止目标程序运行的前提下,通过hotspot的hotswap技术动态加入原本不存在的调试代码。
查看对象个数等
btrace有诸多安全限制,需要增加jvm启动参数-Dcom.sun.btrace.unsafe=true
,并且需要编写代码。
Arthas类似linux shell,直接敲命令解决所有问题,好用太多
可参考:
arthas 运维工具介绍与原理分析
ASM原理可参考ASM详解。主要用了javaagent、ASM字节码增强等技术来替换内存中正在执行的字节码,以将我们增加的监控触发逻辑加入。
curl -O https://alibaba.github.io/arthas/arthas-boot.jar
java -jar arthas-boot.jar
查看一个say
方法的传入参数,且是在抛异常后(-e),只捕获一条符合要求的(要求是第一个参数值为’tom’)。
watch com.chengc.Hello say {
"params[0]","params[1]","params[1][0].keys","params[1][0].values",returnObj} "params[0]=='tom'" -x 2 -n 1 -e
int say(String name, List<Map<String, Object>> records){
try{
...
return 0;
}catch(Exception e){
throw new RuntimeException("xxx")
}
}
这个时候可以得到:
-e
参数所以返回值肯定为null
)命令行图形化
展示当前进程的信息,按ctrl+c可以中断执行。
导出堆内存快照
反编译类
可用来查线上代码版本是不是对的
救急用,线上热更新class
如果只是退出当前的连接,可以用quit
或者exit
命令。Attach到目标进程上的arthas还会继续运行,端口会保持开放,下次连接时可以直接连接上。
如果想完全退出arthas,可以执行stop
命令。
可参考:
官网GCEasy
官网GCViewer
JVisualVM 工具的 “VisualGC” 插件提供了基本的 JMX客户端功能, 还实时显示出 GC事件以及各个内存空间的使用情况。
参考 GC 调优(工具篇) - GC参考手册
jmeter是apache公司基于java开发的一款开源压力测试工具,体积小,功能全,使用方便,是一个比较轻量级的测试工具,使用起来非常简单。
因为jmeter是java开发的,所以运行的时候必须先要安装jdk。
jmeter本身是免安装的,直接解压安装包就可以使用,适用于linux/windows/macos。
参考:
Hprof和Jmap一样可以统计堆内存使用情况、Dump等,但他还能能够展现CPU使用率。
可参考:
java -agentlib:hprof[=options] ToBeProfiledClass
java -Xrunprof[:options] ToBeProfiledClass
javac -J-agentlib:hprof[=options] ToBeProfiledClass
完整选项如下:
Option Name and Value Description Default
--------------------- ----------- -------
heap=dump|sites|all heap profiling all
cpu=samples|times|old CPU usage off
monitor=y|n monitor contention n
format=a|b text(txt) or binary output a
file=<file> write data to file java.hprof[.txt]
net=<host>:<port> send data over a socket off
depth=<size> stack trace depth 4
interval=<ms> sample interval in ms 10
cutoff=<value> output cutoff point 0.0001
lineno=y|n line number in traces? y
thread=y|n thread in traces? n
doe=y|n dump on exit? y
msa=y|n Solaris micro state accounting n
force=y|n force output to <file> y
verbose=y|n print messages about dumps y
开启Hprof Dump
在启动Java程序时,在JVM配置中加上-XX:+HeapDumpOnOutOfMemoryError
,表示在内存出现OOM的时候,把Heap转存(Dump)到磁盘文件以便后续分析。
文件名通常是java_pid<pid>.hprof
,其中pid为该应用的进程号。
随后可以使用JHat或MAT或JVisualVM对,hprof
文件进行分析。
Dump文件路径配置
-XX:HeapDumpPath=<path>
。
注意,该目录必须存在,否则出错!不设置时,如果运行tomcat则放在/tomcat_home/bin
目录下。
切大流量到某个指定机器,用来测试大流量带来的问题。
线上不能使用jmap导出堆快照,否则造成线上业务暂停受较大影响。
正确做法为在启动Java程序时,在JVM配置中加上-XX:+HeapDumpOnOutOfMemoryError
,表示在内存出现OOM的时候,把Heap转存(Dump)到磁盘文件以便后续分析。
文件名通常是java_pid<pid>.hprof
,其中pid为该应用的进程号。
随后可以使用JHat或MAT对,hprof
文件进行分析。
Dump文件路径配置
-XX:HeapDumpPath=<path>
。
注意,该目录必须存在,否则出错!不设置时,如果运行tomcat则放在/tomcat_home/bin
目录下。
JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、hprof使用详解
JVM性能调优监控工具jps、jstack、jmap、jhat、jstat等使用详解
Eclipse Memory Analyzer tool 工具的使用
Java8 Non-Heap 中的metaspace 和compressed class space解释
JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、hprof使用详解
Winsock 的I/O操作:1、 两种I/O模式 阻塞模式:执行I/O操作完成前会一直进行等待,不会将控制权交给程序。套接字 默认为阻塞模式。可以通过多线程技术进行处理。 非阻塞模式:执行I/O操作时,Winsock函数会返回并交出控制权。这种模式使用 起来比较复杂,因为函数在没有运行完成就进行返回,会不断地返回 WSAEWOULDBLOCK错误。但功能强大。为了解决这个问题,提出了进行...
1.普通警告框IOS的SDK中提供了一个方便的类库UIAlertView,配合着不同参数来使用此类可以做出大多数的警告框,如下代码是IOS最简单的警告框。1 UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"你好" message:@"我是普通警告框" delegate:nil cancelButtonTitl...
上一篇写了如何在CDH中集成Flinkhttps://blog.csdn.net/qaz1qaz1qaz2/article/details/118153264本篇记录一下Flink集成并使用Iceberg的过程目录1. 集成1.1 版本1.2 过程1. flink与Iceberg集成的包下载2.下载hive依赖包3.安装依赖包2. 使用2.1 Flink SQL Client2.2 Flink Table Api1. 集成1.1 版本...
STEP1在stc官方网站下载stc-isp烧录软件打开 选择Keil仿真设置-添加型号和头文件到keil中(注意:这里添加到的keil文件目录下必须同时存在UVx和C51文件夹)STEP2打开keil5软件,在Device栏中选择STC库即可...
c++常用函数所在头文件一览 函数 包含 类别 功能 _atold math.h 数学子程序 把字符串转换为浮点数_beginthread process.h 进程控制子程序 启动执行一个新线程_bios
目录一、docker的出现背景二、docker的介绍二、docker的架构图容器仓库总结三、docker的安装1、centos6.8安装docker2、centos7安装docker3、阿里云镜像加速四、docker的使用run指令的实现与原理version指令info指令docker的描述help指令镜像操作命令imag......
1.第二代电子计算机的主要元件是______。个人计算机pc必备的外部设备A.继电器B.晶体管C.电子管D.集成电路答案:B2.以下不属于电子数字计算机特点的是______。A.运算快速B.计算精度高C.形状粗笨D.通用性强答案:C3.______领域是计算机应用中最诱人、也是难度大且目前研究最为活跃的领域之一。个人计算机pc必备的外部设备A.辅助设计B.信息处理C.人工智能D.过程控制答案:C4...
传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=28182818: GcdTime Limit:10 SecMemory Limit:256 MBSubmit:9236Solved:4126[Submit][Status][Discuss]Description给定整数N,求1<=x,y<=...
(context, "接收到短消息:"+address+" 内容:"+fullMessage, Toast.接收广播处理短消息 Manifest.permission.RECEIVE_SMS。//动态注册广播接收。
安装MySQL sudo apt-get install mysql-server 这个应该很简单了,而且我觉得大家在安装方面也没什么太大问题,所以也就不多说了,下面我们来讲讲配置。 配置MySQL 注意,在Ubuntu下MySQL缺省是只允许本地访问的,如果你要其他机器也能够访问的话,那么需要改变/etc/mysql/my.cnf配置文件了!下面我们一步步地来: 默认的M
Servlet登录实例(二)。
<view class="bottom_box"> <view class="enclosure_box" v-if="activityData.attachmentTemplateList.length > 0"> <view class="enclosure_item" v-for="(item, index) in activityData.attachmentTemplateList" :key="index">...