前面东西说完后,现在可以说一些和我们平时进行性能调优相关的东西了,那怎么看和我们JVM性能调优相关的东西呢,其实这对我们开发来说是一个比较头痛的问题,其实我们JDK官网给了一些我们相关的指令,我们可以用这些命令去排查当前JAVA中当前有多少个进程、可以知道我们内存空间中他是一个什么样的结构、哪些对象占用的比较大、哪些对象占用的比较小、还有查看我们的类加载信息、查看GC信息等。

官网:https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/index.html

一、jps

我们不管查什么信息,首先第一个针对的对象肯定是java的进程而言的,所以第一个要说的命令就是查看当前系统的java的进程。在演示之前先随便打开一个自己的java项目,这个只要是开发人员都会有,我就不上传DEMO了。启动项目后然后打开本地的命令行。

输入命令jps后可以看到我启动的项目java进程和进程号PID

接下来所有的操作都可以以这个进程号进行开展

二、jinfo

(1)实时查看和调整JVM配置参数
The jinfo command prints Java configuration information for a specified Java process or core file or a remote debug server.
The configuration information includes Java system properties and Java Virtual Machine (JVM) command-line flags.
(2)查看用法
jinfo -flflag name PID 查看某个java进程的name属性的值
jinfo -flag MaxHeapSize PID 
jinfo -flag UseG1GC PID #查看是否用到了G1,有'-'号表示没有用到

(3)修改
参数只有被标记为manageable的flflags可以被实时修改
jinfo -flag [+|-] PID
jinfo -flag <name>=<value> PID
(4)查看曾经赋过值的一些参数
jinfo -flags PID   #查看全部

三、jstat

查看进程的类的信息和GC的信息

(1)查看虚拟机性能统计信息
The jstat command displays performance statistics for an instrumented Java HotSpot VM. 
The target JVM is identified by its virtual machine identifier, or vmid option.
(2)查看类装载信息
jstat -class PID 1000 10 查看某个java进程的类装载信息,每1000毫秒输出一次,共输出10次

可以通过上面可以看到有多少个类被装载进来了,也可以看到有多少个类被卸载了

(3)查看垃圾收集信息
jstat -gc PID 1000 10

可以看到s0/s1什么一堆信息

四、jstack

前面我们看到了进程、类和gc的信息了,接下来要看的就是要看线程的信息了。

(1)查看线程堆栈信息
The jstack command prints Java stack traces of Java threads for a specified Java process, core file, or remote debug server.
(2)用法
jstack PID

这里面有很多线程,有业务线程和GC线程,查到这些有什么用呢,其实这个其实用处很多,比喻排查死锁情况

(4)排查死锁案例
public class DeadLockDemo {
public static void main(String[] args) {
DeadLock d1=new DeadLock(true);
DeadLock d2=new DeadLock(false);
Thread t1=new Thread(d1);
Thread t2=new Thread(d2);
t1.start();
t2.start();
}
} //定义锁对象
class MyLock{
public static Object obj1=new Object();
public static Object obj2=new Object();
}
//死锁代码
class DeadLock implements Runnable{
private boolean flag;
DeadLock(boolean flag){
this.flag=flag;
}
public void run() {
if(flag) {
while(true) {
synchronized(MyLock.obj1) {
System.out.println(Thread.currentThread().getName()+"----if 获得obj1锁");
synchronized(MyLock.obj2) {
System.out.println(Thread.currentThread().getName()+"--- -if获得obj2锁");
}
}
}
}else {
while(true){
synchronized(MyLock.obj2) {
System.out.println(Thread.currentThread().getName()+"----否则 获得obj2锁");
synchronized(MyLock.obj1) {
System.out.println(Thread.currentThread().getName()+"--- -否则获得obj1锁");
}
}
}
}
}
}

jsack分析

把打印信息拉到最后可以发现

会发现两个线程发生了死锁

五、jmap

上面这些内容看完后其实还有一个很重要的东西没看,那就是运行时数据区堆的运行情况

(1)生成堆转储快照
The jmap command prints shared object memory maps or heap memory details of a specified process, core file, or remote debug server.
(2)打印出堆内存相关信息
jmap -heap PID

(3)dump出堆内存相关信息
jmap -dump:format=b,file=heap.hprof PID

(4)要是在发生堆内存溢出的时候,能自动dump出该文件就好了
一般在开发中,JVM参数可以加上下面两句,这样内存溢出时,会自动dump出该文件
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap.hprof
(5)关于dump下来的文件可以结合工具来分析,这块后面再说。

六、执行引擎

        Person.java源码文件是Java这门高级开发语言,对程序员友好,方便我们开发。javac编译器将Person.java源码文件编译成class文件[我们把这里的编译称为前期编译],交给JVM运行,因为JVM只能认识class字节码文件。同时在不同的操作系统上安装对应版本的JDK,里面包含了各自屏蔽操作系统底层细节的JVM,这样同一份class文件就能运行在不同的操作系统平台之上,得益于JVM。这也是Write Once,Run Anywhere的原因所在。

        最终JVM需要把字节码指令转换为机器码,可以理解为是0101这样的机器语言,这样才能运行在不同的机器上,那么由字节码转变为机器码是谁来做的呢?说白了就是谁来执行这些字节码指令的呢?这就是执行引擎。

6.1、解释执行

Interpreter,解释器逐条把字节码翻译成机器码并执行,跨平台的保证。刚开始执行引擎只采用了解释执行的,但是后来发现某些方法或者代码块被调用执行的特别频繁时,就会把这些代码认定为“热点代码”。

6.2 即时编译器

Just-In-Time compilation(JIT),即时编译器先将字节码编译成对应平台的可执行文件,运行速度快。即时编译器会把这些热点代码编译成与本地平台关联的机器码,并且进行各层次的优化,保存到内存中。

6.3 JVM采用哪种方式

JVM采取的是混合模式,也就是解释+编译的方式,对于大部分不常用的代码,不需要浪费时间将其编译成机器码,只需要用到的时候再以解释的方式运行;对于小部分的热点代码,可以采取编译的方式,追求更高的运行效率。

6.4 即使编译器类型

(1)HotSpot虚拟机里面内置了两个JIT:C1和C2
  • C1也称为Client Compiler,适用于执行时间短或者对启动性能有要求的程序
  • C2也称为Server Compiler,适用于执行时间长或者对峰值性能有要求的程序
(2)Java7开始,HotSpot会使用分层编译的方式
      也就是会结合C1的启动性能优势和C2的峰值性能优势,热点方法会先被C1编译,然后热点方法中的热点会被C2再次编译

6.5 AOT和Graal VM

6.5.1 AOT

在Java9中,引入了AOT(Ahead-Of-Time)编译器,即时编译器是在程序运行过程中,将字节码翻译成机器码。而AOT是在程序运行之前,将字节码转换为机器码
优势 :这样不需要在运行过程中消耗计算机资源来进行即时编译
劣势 :AOT 编译无法得知程序运行时的信息,因此也无法进行基于类层次分析的完全虚方法内联,或者基于程序 profifile 的投机性优化(并非硬性限制,我们可以通过限制运行范围,或者利用上一次运行的程序 profifile 来绕开这两个限制) 

6.5.2 Graal VM

在Java10中,新的JIT编译器Graal被引入它是一个以Java为主要编程语言,面向字节码的编译器。跟C++实现的C1和C2相比,模块化更加明显,也更加容易维护。Graal既可以作为动态编译器,在运行时编译热点方法;也可以作为静态编译器,实现AOT编译。除此之外,它还移除了编程语言之间的边界,并且支持通过即时编译技术,将混杂了不同的编程语言的,代码编译到同一段二进制码之中,从而实现不同语言之间的无缝切换。

JVM常用命令(九)的更多相关文章

  1. JVM常用命令和性能调优建议 [Could not create the Java virtual machine]

    一.查看jvm常用命令jinfo:可以输出并修改运行时的java 进程的opts. jps:与unix上的ps类似,用来显示本地的java进程,可以查看本地运行着几个java程序,并显示他们的进程号. ...

  2. JVM常用命令和性能调优建议

      一.查看jvm常用命令jinfo:可以输出并修改运行时的java 进程的opts. jps:与unix上的ps类似,用来显示本地的java进程,可以查看本地运行着几个java程序,并显示他们的进程 ...

  3. java jvm常用命令工具

    [尊重原创文章出自:http://www.chepoo.com/java-jvm-command-tools.html] 一.概述 程序运行中经常会遇到各种问题,定位问题时通常需要综合各种信息,如系统 ...

  4. JVM 常用命令行工具

    本文部分摘自<深入理解 Java 虚拟机第三版> 基础故障处理工具 Java 开发人员肯定都知道 JDK 的 bin 目录下有许多小工具,这些小工具除了用于编译和运行 Java 程序外,打 ...

  5. JVM 常用命令

    对于有图形化界面的用户来,jconsole就可以搞定,界面使用很简单 还可以查看很多信息,例如检测死锁. 下面是没有图形化界面的系统 可以用命令 : jps 查看jvm 进程 jstack -l  6 ...

  6. Linux 常用命令九 tar

    一.tar命令 tar命令用于打包,解包. gzip命令用于压缩,解压缩. bzip2命令用于压缩,解压缩. 这三个是在linux中常用的,还有一些不常用的. tar打包: wang@wang:~/w ...

  7. 查看jvm常用命令

    jinfo:可以输出并修改运行时的java 进程的opts. jps:与unix上的ps类似,用来显示本地的java进程,可以查看本地运行着几个java程序,并显示他们的进程号. jstat:一个极强 ...

  8. JVM常用命令行工具1

    1.jps [options][hostid]:查看虚拟机进程状况 -l 输出主类全名,如果进程执行的是jar包,输出jar包路径.-q 只输出LVMID. -m输出虚拟机进程启动时传递给主类main ...

  9. jvm常用命令

    jps // 查看Java进程ID和main方法类名 jstack <进程ID> // 查看该进程的所有栈信息 jstack -l <进程ID> // 查看该进程的所有栈信息, ...

随机推荐

  1. Codeforces1132A——Regular Bracket Sequence(水题)

    Regular Bracket Sequence time limit per test:1 second memory limit per test:256 megabytes input:stan ...

  2. Null和空值对于avg计算时产生的影响以及处理

    为什么要关注这一块呢:1.面试中可能会有涉及 2.工作中真的也可能会用,既然有可能我也用过,就拿出来跟大家分享一下,上一篇的博文,数据已准备好就不做数据准备的介绍了. step1:select * f ...

  3. git下载

    git快速下载地址:https://github.com/waylau/git-for-win

  4. RSA非对称加密算法实现:Golang

    RSA是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.当时他们三人都在麻省理工学院工作.RSA ...

  5. js tab栏切换

    <!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" ...

  6. vue 因为使用scope后选择器和标签出现[data-v

    使用scope的以后出现datd-v,例如: <div data-v-2311c06a class="button-warp"> <button data-v-2 ...

  7. vue2.0组件库

    UI组件 element - 饿了么出品的Vue2的web UI工具套件 Vux - 基于Vue和WeUI的组件库 mint-ui - Vue 2的移动UI元素 iview - 基于 Vuejs 的开 ...

  8. PAT 乙级 1001. 害死人不偿命的(3n+1)猜想 (15)(C语言描述)

    卡拉兹(Callatz)猜想: 对任何一个自然数n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把(3n+1)砍掉一半.这样一直反复砍下去,最后一定在某一步得到n=1.卡拉兹在1950年的世界数 ...

  9. 三分钟:极速体验JAVA版目标检测(YOLO4)

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  10. 记一次线上SpringCloud-Feign请求服务超时异常排查

    由于近期线上单量暴涨,第三方反馈部分工单业务存在查询处理失败现象,经排查是当前系统通过FeignClient调用下游系统出现部分超时失败(异常代码贴在下方). Caused by: feign.Ret ...