• 查看Java进程:jps
  • 查看线程堆栈命令:jstack命令
  • 打印内存映射,制作堆Dump命令:Jmap
    • 查看java 堆(heap)使用情况,执行命令:
    • 查看堆内存(histogram)中的对象数量及大小。执行命令:
  • 性能监控工具命令:jstat
  • 参考资料

查看Java进程:jps

用法介绍

jps命令:显示所有进程号和短的类名称

Jps –q 命令:只显示进程号

Jps –l 用于传输主函数的完整路径

Jps –v 显示传递给Java虚拟机的参数(感觉这个命令才是完美,把虚拟机的一些参数全都打印出来)

查看线程堆栈命令:jstack命令

Jstack命令主要用来查看Java线程的调用堆栈的,可以用来分析线程问题(如死锁)。谈到线程,在Java里面,线程一共有6中状态

  • New 新建 ————- 不会出现在dump中
  • Runnable 正在运行中——–在虚拟机内执行
  • Blocked 阻塞————受阻塞,并等待监视器锁
  • Waiting 等待————无限期等待另一个线程执行特定操作
  • Timed_waiting 超时等待————有时限等待另一个线程的操作
  • Terminated 终止/结束————已退出的

Monitor
在多线程的 JAVA程序中,实现线程之间的同步,就要说说 Monitor。 Monitor是 Java中用以实现线程之间的互斥与协作的主要手段,它可以看成是对象或者 Class的锁。每一个对象都有,也仅有一个 monitor。下 面这个图,描述了线程和 Monitor之间关系,以 及线程的状态转换图:

进入区(Entrt Set):

表示线程通过synchronized要求获取对象的锁。如果对象未被锁住,则迚入拥有者;否则则在进入区等待。一旦对象锁被其他线程释放,立即参与竞争。

拥有者(The Owner):

表示某一线程成功竞争到对象锁。

等待区(Wait Set):

表示线程通过对象的wait方法,释放对象的锁,并在等待区等待被唤醒。

从图中可以看出,一个 Monitor在某个时刻,只能被一个线程拥有,该线程就是 “Active Thread”,而其它线程都是 “Waiting Thread”,分别在两个队列 “ Entry Set”和 “Wait Set”里面等候。在 “Entry Set”中等待的线程状态是 “Waiting for monitor entry”,而在 “Wait Set”中等待的线程状态是 “in Object.wait()”。 先看 “Entry Set”里面的线程。我们称被 synchronized保护起来的代码段为临界区。当一个线程申请进入临界区时,它就进入了 “Entry Set”队列。对应的 code就像:

synchronized(obj) {
.........}

调用修饰
表示线程在方法调用时,额外的重要的操作。线程Dump分析的重要信息。修饰上方的方法调用。
locked <地址> 目标:使用synchronized申请对象锁成功,监视器的拥有者。
waiting to lock <地址> 目标:使用synchronized申请对象锁未成功,在迚入区等待。
waiting on <地址> 目标:使用synchronized申请对象锁成功后,释放锁幵在等待区等待。
parking to wait for <地址> 目标

locked

at oracle.jdbc.driver.PhysicalConnection.prepareStatement
- locked <0x00002aab63bf7f58> (a oracle.jdbc.driver.T4CConnection)
at oracle.jdbc.driver.PhysicalConnection.prepareStatement
- locked <0x00002aab63bf7f58> (a oracle.jdbc.driver.T4CConnection)
at com.jiuqi.dna.core.internal.db.datasource.PooledConnection.prepareStatement

通过synchronized关键字,成功获取到了对象的锁,成为监视器的拥有者,在临界区内操作。对象锁是可以线程重入的。

waiting to lock

at com.jiuqi.dna.core.impl.CacheHolder.isVisibleIn(CacheHolder.java:165)
- waiting to lock <0x0000000097ba9aa8> (a CacheHolder)
at com.jiuqi.dna.core.impl.CacheGroup$Index.findHolder
at com.jiuqi.dna.core.impl.ContextImpl.find
at com.jiuqi.dna.bap.basedata.common.util.BaseDataCenter.findInfo

通过synchronized关键字,没有获取到了对象的锁,线程在监视器的进入区等待。在调用栈顶出现,线程状态为Blocked。

waiting on

at java.lang.Object.wait(Native Method)
- waiting on <0x00000000da2defb0> (a WorkingThread)
at com.jiuqi.dna.core.impl.WorkingManager.getWorkToDo
- locked <0x00000000da2defb0> (a WorkingThread)
at com.jiuqi.dna.core.impl.WorkingThread.run

通过synchronized关键字,成功获取到了对象的锁后,调用了wait方法,进入对象的等待区等待。在调用栈顶出现,线程状态为WAITING或TIMED_WATING。

parking to wait for
park是基本的线程阻塞原语,不通过监视器在对象上阻塞。随concurrent包会出现的新的机制,不synchronized体系不同。

线程动作
线程状态产生的原因
runnable:状态一般为RUNNABLE。
in Object.wait():等待区等待,状态为WAITING或TIMED_WAITING。
waiting for monitor entry:进入区等待,状态为BLOCKED。
waiting on condition:等待区等待、被park。
sleeping:休眠的线程,调用了Thread.sleep()。

Wait on condition 该状态出现在线程等待某个条件的发生。具体是什么原因,可以结合 stacktrace来分析。 最常见的情况就是线程处于sleep状态,等待被唤醒。 常见的情况还有等待网络IO:在java引入nio之前,对于每个网络连接,都有一个对应的线程来处理网络的读写操作,即使没有可读写的数据,线程仍然阻塞在读写操作上,这样有可能造成资源浪费,而且给操作系统的线程调度也带来压力。在 NewIO里采用了新的机制,编写的服务器程序的性能和可扩展性都得到提高。 正等待网络读写,这可能是一个网络瓶颈的征兆。因为网络阻塞导致线程无法执行。一种情况是网络非常忙,几 乎消耗了所有的带宽,仍然有大量数据等待网络读 写;另一种情况也可能是网络空闲,但由于路由等问题,导致包无法正常的到达。所以要结合系统的一些性能观察工具来综合分析,比如 netstat统计单位时间的发送包的数目,如果很明显超过了所在网络带宽的限制 ; 观察 cpu的利用率,如果系统态的 CPU时间,相对于用户态的 CPU时间比例较高;如果程序运行在 Solaris 10平台上,可以用 dtrace工具看系统调用的情况,如果观察到 read/write的系统调用的次数或者运行时间遥遥领先;这些都指向由于网络带宽所限导致的网络瓶颈。(来自http://www.blogjava.net/jzone/articles/303979.html)

jstack 命令详解

简单介绍:

F当’jstack [-l] pid’没有相应的时候强制打印栈信息 -l长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表. -m打印java和native c/c++框架的所有栈信息. -h | -help打印帮助信息 pid 需要被打印配置信息的java进程id,可以用jps查询.

第一个实战代码:

/*** Created by Cser_W on 2018/7/10.*/
public class JstackDemo {public static void main(String[] args){while (true) {//do nothing}}
}

先利用 jps 查看进程号

利用jstack 进程号查看线程堆栈信息,如果发现自己写的代码一直处于Runnable状态,这有很大可能是自己写了个死循环。
第二个实战代码

/*** Created by Cser_W on 2018/7/10.*/
public class JstackDemo1 {public static void main(String[] args){Thread thread = new Thread(new Thread1());thread.start();}
}
class Thread1 extends Thread {@Overridepublic void run(){while (true) {System.out.println(1);}}
}


我们能看到:
线程的状态: WAITING 线程的调用栈 线程的当前锁住的资源: < < <0x00000000da380ee0>>> 线程当前等待的资源:< < <0x00000000da380ee0>>>

为什么同时锁住的等待同一个资源:
线程的执行中,先获得了这个对象的 Monitor(对应于 locked < <0x00000000da380ee0>>)。当执行到 obj.wait(), 线程即放弃了 Monitor的所有权,进入 “wait set”队列(对应于 waiting on < <0x00000000da380ee0>> )。

死锁模拟实战

package com.wxy.test;/*** Created by Cser_W on 2018/7/10.*/
public class JstackDemo2 {public static void main(String[] args){Thread thread1 = new Thread(new DeadLockClass(true));Thread thread2 = new Thread((new DeadLockClass(false)));thread1.start();thread2.start();}
}
class DeadLockClass implements Runnable {public boolean flag;DeadLockClass(boolean flag) {this.flag = flag;}@Overridepublic void run() {if (flag) {while (true) {synchronized (Suo.o1) {System.out.println("o1" + Thread.currentThread().getName());synchronized (Suo.o2) {System.out.println("o2" + Thread.currentThread().getName());}}}} else {while (true) {synchronized (Suo.o2) {System.out.println("o2" + Thread.currentThread().getName());synchronized (Suo.o1) {System.out.println("o1" + Thread.currentThread().getName());}}}}}
}
class Suo {static Object o1 = new Object();static Object o2 = new Object();
}

运行输出:

上图已经锁死,只要两个线程都启动起来,必定会发生死锁。这个时候赶紧拿jstack练手了
用jstack命令显示:

打印内存映射,制作堆Dump命令:Jmap

堆map的概述

堆Dump是反应Java堆使用情况的内存镜像,其中主要包括系统信息、虚拟机属性、完整的线程Dump、所有类和对象的状态等。 一般,在内存不足、GC异常等情况下,我们就会怀疑有内存泄露。这个时候我们就可以制作堆Dump来查看具体情况

用法摘要

Usage:jmap [option] <pid>(to connect to running process)jmap [option] <executable <core>(to connect to a core file)jmap [option] [server_id@]<remote server IP or hostname>(to connect to remote debug server)where <option> is one of:<none>               to print same info as Solaris pmap-heap                to print java heap summary-histo[:live]        to print histogram of java object heap; if the "live"suboption is specified, only count live objects-permstat            to print permanent generation statistics-finalizerinfo       to print information on objects awaiting finalization-dump:<dump-options> to dump java heap in hprof binary formatdump-options:live         dump only live objects; if not specified,all objects in the heap are dumped.format=b     binary formatfile=<file>  dump heap to <file>Example: jmap -dump:live,format=b,file=heap.bin <pid>-F                   force. Use with -dump:<dump-options> <pid> or -histoto force a heap dump or histogram when <pid> does notrespond. The "live" suboption is not supportedin this mode.-h | -help           to print this help message-J<flag>             to pass <flag> directly to the runtime system

指定进程号(pid)的进程 jmap [ option ] 指定核心文件 jmap [ option ] 指定远程调试服务器jmap [ option ] [server-id@]
参数:
option 选项参数是互斥的(不可同时使用)。想要使用选项参数,直接跟在命令名称后即可。
pid 需要打印配置信息的进程ID。该进程必须是一个Java进程。想要获取运行的Java进程列表,你可以使用jps。
executable 产生核心dump的Java可执行文件。
core 需要打印配置信息的核心文件。
remote-hostname-or-IP 远程调试服务器的(请查看jsadebugd)主机名或IP地址。
server-id 可选的唯一id,如果相同的远程主机上运行了多台调试服务器,用此选项参数标识服务器。
选项:
如果使用不带选项参数的jmap打印共享对象映射,将会打印目标虚拟机中加载的每个共享对象的起始地址、映射大小以及共享对象文件的路径全称。这与Solaris的pmap工具比较相似。
-dump:[live,]format=b,file= 以hprof二进制格式转储Java堆到指定filename的文件中。live子选项是可选的。如果指定了live子选项,堆中只有活动的对象会被转储。想要浏览heap dump,你可以使用jhat(Java堆分析工具)读取生成的文件。
-finalizerinfo 打印等待终结的对象信息。
-heap 打印一个堆的摘要信息,包括使用的GC算法、堆配置信息和generation wise heap usage。
-histo[:live] 打印堆的柱状图。其中包括每个Java类、对象数量、内存大小(单位:字节)、完全限定的类名。打印的虚拟机内部的类名称将会带有一个’*’前缀。如果指定了live子选项,则只计算活动的对象。
-permstat 打印Java堆内存的永久保存区域的类加载器的智能统计信息。对于每个类加载器而言,它的名称、活跃度、地址、父类加载器、它所加载的类的数量和大小都会被打印。此外,包含的字符串数量和大小也会被打印。
-F 强制模式。如果指定的pid没有响应,请使用jmap -dump或jmap -histo选项。此模式下,不支持live子选项。
-h 打印帮助信息。
-help 打印帮助信息。
-J 指定传递给运行jmap的JVM的参数。

查看java 堆(heap)使用情况,执行命令:

Jmap –heap pid

查看堆内存(histogram)中的对象数量及大小。执行命令:

Jmap –histo pid

总结:
1. 如果程序内存不足或者频繁GC,很有可能存在内存泄露情况,这时候就要借助Java堆Dump查看对象的情况。
2.要制作堆Dump可以直接使用jvm自带的jmap命令
3.可以先使用jmap -heap命令查看堆的使用情况,看一下各个堆空间的占用情况。
4.使用jmap -histo:[live]查看堆内存中的对象的情况。如果有大量对象在持续被引用,并没有被释放掉,那就产生了内存泄露,就要结合代码,把不用的对象释放掉。
5.也可以使用 jmap -dump:format=b,file=命令将堆信息保存到一个文件中,再借助jhat命令查看详细内容
6.在内存出现泄露、溢出或者其它前提条件下,建议多dump几次内存,把内存文件进行编号归档,便于后续内存整理分析。

性能监控工具命令:jstat

用法讲解

jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

参数解释:
Option — 选项,我们一般使用 -gcutil 查看gc情况
vmid — VM的进程号,即当前运行的java进程号
interval– 间隔时间,单位为秒或者毫秒
count — 打印次数,如果缺省则打印无数次
参数 interval 和 count 代表查询间隔和次数,如果省略这两个参数,说明只查询一次。

示例:
Jstat –gc 4100 250 5

上图中参数的意思:

S0C 年轻代中第一个survivor(幸存区)的容量 (字节)
S0U 年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
EC 年轻代中Eden(伊甸园)的容量 (字节)
EU 年轻代中Eden(伊甸园)目前已使用空间 (字节)
OU Old代目前已使用空间 (字节)
PC Perm(持久代)的容量 (字节)
PU Perm(持久代)目前已使用空间 (字节)
YGC 从应用程序启动到采样时年轻代中gc次数
FGC 从应用程序启动到采样时old代(全gc)gc次数
FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s)
GCT 从应用程序启动到采样时gc用的总时间(s)

Jstat –class 4100 250 5 显示加载class的数量,及所占空间等信息。

Loaded 装载的类的数量
Unloaded 卸载类的数量
Bytes 卸载类的字节数
Time 装载和卸载类所花费的时间

jstat -compiler 显示VM实时编译的数量等信息

Compiled 编译任务执行数量
Invalid 编译任务执行失效数量
Time 编译任务消耗时间
FailedType 最后一个编译失败任务的类型
FailedMethod 最后一个编译失败任务所在的类及方法

Jstat –gccapacity 4100

NGCMN 年轻代(young)中初始化(最小)的大小(字节)
NGC 年轻代(young)中当前的容量 (字节)
S0C 年轻代中第一个survivor(幸存区)的容量 (字节)
S1C 年轻代中第二个survivor(幸存区)的容量 (字节)
EC 年轻代中Eden(伊甸园)的容量 (字节)
OGCMN old代中初始化(最小)的大小 (字节)
OGCMX old代的最大容量(字节)
OGC old代当前新生成的容量 (字节)
OC Old代的容量 (字节)
PGCMN perm代中初始化(最小)的大小 (字节)
PGCMX perm代的最大容量 (字节)
PGC perm代当前新生成的容量 (字节)
PC Perm(持久代)的容量 (字节)
YGC 从应用程序启动到采样时年轻代中gc次数
FGC 从应用程序启动到采样时old代(全gc)gc次数

参考资料

【Java命令学习系列(二)-Jstack】http://www.hollischuang.com/archives/110
【Java命令学习系列(三)—Jmap】http://www.hollischuang.com/archives/303
【Java命令学习系列(四)—jstat】http://www.hollischuang.com/archives/481

Java常用命令:jps、jstack、jmap、jstat(带有实例教程)相关推荐

  1. Java常用命令汇总(笔记)

    Java常用命令汇总 文章目录 Java常用命令汇总 1.javac 将文件编译成.class文件 2.java 执行 .class文件,若类中没有main函数,则不能执行. 3.jar 主要用于打包 ...

  2. linux lw3m多行文本使用,linux常用命令以及一些常见问题和解决方法教程.docx

    linux常用命令以及一些常见问题和解决方法教程 端口以及ip之间抓包1.监视指定网络接口的数据包tcpdump -i eth1如果不指定网卡,默认tcpdump只会监视第一个网络接口,一般是eth0 ...

  3. java常用命令javac、javap、jps、jstack

    本文参考http://www.hollischuang.com/?s=java%E5%91%BD%E4%BB%A4%E5%AD%A6%E4%B9%A0 作为一个java开发人员,应该了解java常用指 ...

  4. JVM性能调优监控工具专题一:JVM自带性能调优工具(jps,jstack,jmap,jhat,jstat,hprof)...

    2019独角兽企业重金招聘Python工程师标准>>> 前提概要:         JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外 ...

  5. java常用命令汇总

    本文参考多篇大神的文章,不再一一列举,在此表示感谢! 1.进程和线程 1.1 jps 查看进程号 pid  jinfo查看参数 ps -ef | grep java | grep -v grep ro ...

  6. Java常用命令及Java Dump

    线程Dump,包含所有线程的运行状态.纯文本格式. 堆Dump,包含线程Dump,幵包含所有堆对象的状态.二进制格式. Java Dump方法 1.使用Java虚拟机制作Dump 指示虚拟机在发生内存 ...

  7. java 版本查看命令_查看Java版本命令如何查看?Java常用命令详解

    现在程序员开发项目都在使用工具,很多人可能都忘记了Java自带命令,下面就让我来介绍些吧. 1.java.exe: 运行java程序,这个相信每一位用Java的人知道了. 2.javac.exe: 编 ...

  8. Java常用命令及参数

    Java的基本指令参数 javac [-d 目录|-verbose] file java [-classpath(cp) dir] file jar -zcvf dir file javap [-pr ...

  9. FFmpeg最常用命令参数详解及应用实例

    FFMPEG堪称自由软件中最完备的一套多媒体支持库,它几乎实现了所有当下常见的数据封装格式.多媒体传输协议以及音视频编解码器,提供了录制.转换以及流化音视频的完整解决方案. ffmpeg命令行参数解释 ...

  10. java实现备忘录_JAVA中的备忘录模式实例教程

    原文链接  作者:Pankaj Kumar 译者:f0tlo <1357654289@qq.com> 备忘录模式是一种行为模式.备忘录模式用于保存对象当前状态,并且在之后可以再次使用此状态 ...

最新文章

  1. “jQuery风暴” 推荐及配套代码下载
  2. 1.3:Render Pipeline and GPU Pipeline
  3. 计算机基础7试题,大学计算机应用基础试题
  4. [css] 举例说明CSS特性检测的方式有哪些?
  5. python中库是什么意思_python库是什么意思
  6. 游戏开发之C++类和对象相关概念实例(C++)
  7. ELK详解(七)——Kibana部署
  8. Rust: codewars 的Count of positives / sum of negatives
  9. 基于51单片机的循迹小车
  10. 2022年计算机软件水平考试数据库系统工程师(中级)练习题及答案
  11. [Fondar]手机屏幕驱动板HDMI接口USB触摸使用步骤
  12. centos7 单机安装 greenplum6
  13. 【BZOJ】2286: [Sdoi2011消耗战【虚树DP】
  14. CAD对话框不见后要如何调出
  15. 计算机g级的存储是,客户说他的电脑高端,支持480G内存与16G显卡升级,有谁见过?...
  16. 2022谷粒商城学习笔记(二十二)rabbitMQ学习
  17. 微信的服务器域名地址,微信服务器域名设置
  18. mysql分区表去重复_MySQL分区表管理
  19. elasticsearch-数据聚合
  20. 闲谈IPv6-IPv6地址聚类分配原则于源地址选择的关系

热门文章

  1. ROC和 区别p值和q值
  2. css动画效果网站集合
  3. 论html5十大优点
  4. mysql基于Python的影院会员管理系统的设计与实现毕业设计源码131621
  5. Linux 常见问题
  6. 4种最常用的诡辩方法
  7. 微信公众号自定义菜单修改
  8. Pocket PC 基础知识
  9. 金字塔结构式表达利器
  10. 前端实现在线预览文档(pdf、doc文件)