JVM常用命令解析

Stella981
• 阅读 576

命令行:

  1. jps:虚拟机进程状况工具
  2. jstat:虚拟机统计信息监视工具
  3. jinfo:java配置信息工具
  4. jmap:java内存映射工具
  5. jhat:虚拟机堆转储快照分析工具
  6. jstack:java堆栈跟踪工具
  7. hsdis:jit生成代码反编汇
  8. 目录:D:\Program Files\jdk1.8.0_05\bin
  9. strace命令

可视化工具:

  1. jconsole:java监视与管理控制台
  2. visualvm:多合一故障处理工具

一、jps

https://blog.csdn.net/luxideyao/article/details/50506092

 jps是jdk提供的一个查看当前java进程的小工具, 可以看做是JavaVirtual Machine Process Status Tool的缩写。非常简单实用。

       命令格式:jps [options ] [ hostid ] 

       [options]选项 :

-q:仅输出VM标识符,不包括classname,jar name,arguments in main method 

-m:输出main method的参数 

-l:输出完全的包名,应用主类名,jar的完全路径名 

-v:输出jvm参数 

-V:输出通过flag文件传递到JVM中的参数(.hotspotrc文件或-XX:Flags=所指定的文件 

-Joption:传递参数到vm,例如:-J-Xms512m

        [hostid]:

[protocol:][[//]hostname][:port][/servername]

        命令的输出格式 :

lvmid [ [ classname| JARfilename | "Unknown"] [ arg* ] [ jvmarg* ] ]

注意:如果需要查看其他机器上的jvm进程,需要在待查看机器上启动jstatd。

二、jstat

定义:

https://blog.csdn.net/zhaozheng7758/article/details/8623549

参数:

l  class (类加载器) 

l  compiler (JIT) 

l  gc (GC堆状态) 

l  gccapacity (各区大小) 

l  gccause (最近一次GC统计和原因) 

l  gcnew (新区统计)

l  gcnewcapacity (新区大小)

l  gcold (老区统计)

l  gcoldcapacity (老区大小)

l  gcpermcapacity (永久区大小)

l  gcutil (GC统计汇总)

l  printcompilation (HotSpot编译统计)

jstat -gc 统计GC信息

一些术语的中文解释: 

S0C:年轻代中第一个survivor(幸存区)的容量 (字节) 

S1C:年轻代中第二个survivor(幸存区)的容量 (字节) 

S0U:年轻代中第一个survivor(幸存区)目前已使用空间 (字节) 

S1U:年轻代中第二个survivor(幸存区)目前已使用空间 (字节) 

EC:年轻代中Eden(伊甸园)的容量 (字节) 

EU:年轻代中Eden(伊甸园)目前已使用空间 (字节) 

OC:Old代的容量 (字节) 

OU:Old代目前已使用空间 (字节) 

PC:Perm(持久代)的容量 (字节) 

PU:Perm(持久代)目前已使用空间 (字节) 

YGC:从应用程序启动到采样时年轻代中gc次数 

YGCT:从应用程序启动到采样时年轻代中gc所用时间(s) 

FGC:从应用程序启动到采样时old代(全gc)gc次数 

FGCT:从应用程序启动到采样时old代(全gc)gc所用时间(s) 

GCT:从应用程序启动到采样时gc用的总时间(s) 

jstat -gccapacity :

可以显示,VM内存中三代(young,old,perm)对象的使用和占用大小

指定java程序运行内存大小

-Xms -Xmx -Xmn 等,然后观察jstat的结果

增加gc参数,java程序自动输出gc日志

vm option: -Xms20M -Xmx20M -Xmn10M

-verbose:gc -XX:+PrintGCDetails -XX:SurvivorRatio=8

说明:

-XX:+PrintGCDetails参数用于告诉虚拟机在发生垃圾收集行为时打印内存回收日志,并且在进程退出的时候输出当前内存的各区域分配情况。

输出日志:

[GC (System.gc()) [PSYoungGen: 7497K->64K(236032K)] 35038K->27604K(1022464K), 0.0022938 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[Full GC (System.gc()) [PSYoungGen: 64K->0K(236032K)] [ParOldGen: 27540K->27540K(786432K)] 27604K->27540K(1022464K), [Metaspace: 40881K->40881K(1087488K)], 0.0429459 secs] [Times: user=0.09 sys=0.00, real=0.04 secs]

https://www.cnblogs.com/xuezhiyizu1120/p/6237510.html

使用jinfo动态修改程序gc参数,协助调试

jinfo -flag +PrintGCDetails

jinfo -flag +PrintGC

jinfo -flag +PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式)

jinfo -flag +PrintGCDateStamps 输出GC的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)

jinfo -flag +PrintHeapAtGC 在进行GC的前后打印出堆的信息

jinfo -flag -Xloggc:../logs/gc.log 日志文件的输出路径

-verbose:gc -Xloggc:$CATALINA_HOME/logs/gc.log

-Xms100m -Xmx100m -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -verbose:gc -Xloggc:/usr/local/e6atlasbus/canbus/canbus-server/gc_logs/gc.log

更改gc参数

https://www.cnblogs.com/gouge/p/9112782.html

三、jinfo

jinfo 是jdk自带的一个工具,它可以用来查看正在运行的java应用程序的扩展参数(JVM中-X标示的参数);甚至支持在运行时修改部分参数。

jinfo 223536 > tmp/jinfo.txt 获取jvm进程的所有信息

关键字:VM Flags

动态修改命令:

通过以下的命令你便能看到JVM中哪些flag可以被jinfo动态修改:

java -XX:+PrintFlagsFinal -version | grep manageable

https://blog.csdn.net/liuxiao723846/article/details/72701414

四、jmap

jmap命令(Java Memory Map)是其中之一。主要用于打印指定Java进程(或核心文件、远程调试服务器)的共享对象内存映射或堆内存细节。

jmap命令可以获得运行中的jvm的堆的快照,从而可以离线分析堆,以检查内存泄漏,检查一些严重影响性能的大对象的创建,检查系统中什么对象最多,各种对象所占内存的大小等等。可以使用jmap生成Heap Dump。 

java memory = direct memory(直接内存) + jvm memory(MaxPermSize +Xmx)

JVM直接内存:

直接内存区并不是 JVM 管理的内存区域的一部分,而是其之外的。该区域也会在 Java 开发中使用到,并且存在导致内存溢出的隐患。

https://blog.csdn.net/leaf_0303/article/details/78961936

深入理解JVM之JVM内存区域与内存分配

https://www.cnblogs.com/wangjzh/p/5258254.html

常用命令:

jmap -heap 查看堆内存

jmap -histo:live 查看对内对象

jmap -dump:live,format=b,file=/f/dump.dat 导出堆快照

jhat /f/dump.dat 分析dump文件

https://www.cnblogs.com/kongzhongqijing/articles/3621163.html

dump文件分析

jvisualvm

OQL 分析dump文件 https://www.aliyun.com/jiaocheng/299417.html

select x from com.e6yun.preprocessor.processor.jcmd.JCmdObject x

dump文件中的线程分析->jstack命令

总结

1.如果程序内存不足或者频繁GC,很有可能存在内存泄露情况,这时候就要借助Java堆Dump查看对象的情况。

2.要制作堆Dump可以直接使用jvm自带的jmap命令

3.可以先使用jmap -heap命令查看堆的使用情况,看一下各个堆空间的占用情况。

4.使用jmap -histo:[live]查看堆内存中的对象的情况。如果有大量对象在持续被引用,并没有被释放掉,那就产生了内存泄露,就要结合代码,把不用的对象释放掉。

5.也可以使用 jmap -dump:format=b,file=命令将堆信息保存到一个文件中,再借助jhat命令查看详细内容

6.在内存出现泄露、溢出或者其它前提条件下,建议多dump几次内存,把内存文件进行编号归档,便于后续内存整理分析。

7.在用cms gc的情况下,执行jmap -heap有些时候会导致进程变T,因此强烈建议别执行这个命令,如果想获取内存目前每个区域的使用状况,可通过jstat -gc或jstat -gccapacity来拿到。

五、jhat

jhat也是jdk内置的工具之一。主要是用来分析java堆的命令,可以将堆中的对象以html的形式显示出来,包括对象的数量,大小等等,并支持对象查询语言。

https://www.cnblogs.com/baihuitestsoftware/articles/6406271.html

jhat /f/dump.dat 分析dump文件

使用jvisualvm可视化工具替代

六、jstack

jstack命令主要用生成java虚拟机当前时刻的线程快照,来查看Java线程的调用堆栈的,可以用来分析线程问题(如死锁)。

http://www.cnblogs.com/kongzhongqijing/articles/3630264.html

命令格式:

jstack [ option ] pid

jstack [ option ] executable core

jstack [ option ] [server-id@]remote-hostname-or-IP

常用参数说明

1)options: 

executable Java executable from which the core dump was produced.(可能是产生core dump的java可执行程序)

core 将被打印信息的core dump文件

remote-hostname-or-IP 远程debug服务的主机名或ip

server-id 唯一id,假如一台主机上多个远程debug服务 

2)基本参数:

-F 当’jstack [-l] pid’没有相应的时候强制打印栈信息,如果直接jstack无响应时,用于强制jstack),一般情况不需要使用

-l 长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表,会使得JVM停顿得长久得多(可能会差很多倍,比如普通的jstack可能几毫秒和一次GC没区别,加了-l 就是近一秒的时间),-l 建议不要用。一般情况不需要使用

-m 打印java和native c/c++框架的所有栈信息.可以打印JVM的堆栈,显示上Native的栈帧,一般应用排查不需要使用

-h | -help 打印帮助信息

pid 需要被打印配置信息的java进程id,可以用jps查询.

线程状态:

NEW

未启动的。不会出现在Dump中。

RUNNABLE

在虚拟机内执行的。运行中状态,可能里面还能看到locked字样,表明它获得了某把锁。

BLOCKED

受阻塞并等待监视器锁。被某个锁(synchronizers)給block住了。

WATING

无限期等待另一个线程执行特定操作。等待某个condition或monitor发生,一般停留在park(), wait(), sleep(),join() 等语句里。

TIMED_WATING

有时限的等待另一个线程的特定操作。和WAITING的区别是wait() 等语句加上了时间限制 wait(timeout)。

TERMINATED

已退出的。

Monitor

在多线程的 JAVA程序中,实现线程之间的同步,就要说说 Monitor。 Monitor是 Java中用以实现线程之间的互斥与协作的主要手段,它可以看成是对象或者 Class的锁。每一个对象都有,也仅有一个 monitor。这就是wait,notify等方法在Object类的原因。

调用修饰

表示线程在方法调用时,额外的重要的操作。线程Dump分析的重要信息。修饰上方的方法调用。

locked <地址> 目标:使用synchronized申请对象锁成功,监视器的拥有者。

waiting to lock <地址> 目标:使用synchronized申请对象锁未成功,在迚入区等待。

waiting on <地址> 目标:使用synchronized申请对象锁成功后,释放锁幵在等待区等待。

parking to wait for <地址> 目标

线程动作,线程状态产生的原因

runnable:状态一般为RUNNABLE。

in Object.wait():等待区等待,状态为WAITING或TIMED_WAITING。

waiting for monitor entry:进入区等待,状态为BLOCKED。

waiting on condition:等待区等待、被park。

sleeping:休眠的线程,调用了Thread.sleep()。

jstack 解决问题实例

http://www.iteye.com/topic/1114219

http://note.youdao.com/noteshare?id=4e05478b110f1d22fbaeb3a740671a00

分析问题入手点总结:

wait on monitor entry: 被阻塞的,肯定有问题

runnable : 注意IO线程

in Object.wait(): 注意非线程池等待

分析经验:

对于jstack做的ThreadDump的栈,可以反映如下信息:

  1. 如果某个相同的call stack经常出现, 我们有80%的以上的理由确定这个代码存在性能问题(读网络的部分除外);
  2. 如果相同的call stack出现在同一个线程上(tid)上, 我们很很大理由相信, 这段代码可能存在较多的循环或者死循环;
  3. 如果某call stack经常出现, 并且里面带有lock,请检查一下这个lock的产生的原因, 可能是全局lock造成了性能问题;
  4. 在一个不大压力的群集里(w<2), 我们是很少拿到带有业务代码的stack的, 并且一般在一个完整stack中, 最多只有1-2业务代码的stack,
  5. 如果经常出现, 一定要检查代码, 是否出现性能问题。
  6. 如果你怀疑有dead lock问题, 那么请把所有的lock id找出来,看看是不是出现重复的lock id。

频繁GC问题或内存溢出问题

一、使用jps查看线程ID

二、使用jstat -gc 3331 250 20 查看gc情况,一般比较关注PERM区的情况,查看GC的增长情况。

三、使用jstat -gccause:额外输出上次GC原因

四、使用jmap -dump:format=b,file=heapDump 3331生成堆转储文件

五、使用jhat或者可视化工具(Eclipse Memory Analyzer 、IBM HeapAnalyzer)分析堆情况。

六、结合代码解决内存溢出或泄露问题。

死锁问题

一、使用jps查看线程ID

二、使用jstack 3331:查看线程情况

六、hsdis

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这