查看java进程

1实时查看和调整jvm配置参数

2查看用法
jinfo -flag name PID查看某个java进程的name属性的值
jinfo -flag MaxHeapSize PID
jinfo -flag UseG1GC PID

修改
参数只能被标记为manageable的flags可以被实时修改
jinfo -flag 【+|-】PID
jinfo -flag = PID
(4)查看曾经赋过值的一些参数
jinfo -flags PID

(1)查看虚拟机性能统计信息

(2)查看类装载信息
jstat -class PID 1000 10查看某个java进程的类装载信息,每1000毫秒输出一次,共输出10次
**
**
(3)查看垃圾收集信息
jstat -gc PID 1000 10

(1)查看线程堆栈信息

(2)用法
jstack PID

(3)排查死锁案例





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

(1)生成堆转存储快照

(2)打印出堆内存相关信息
jmap -heap PID
jinfo - flag UsePSAdaptiveSurvivorSizePolicy 35352
-XX:SurvivorRation=8

(3)jmap -dump: format=b,file=heap.hprof PID

(4)要是发生堆内存溢出的时候,能自动dump出该文件就好了
一般在开发中,jvm参数可以加上下面两句,这样内存溢出时,会自动dump出该文件
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap.hprof
设置堆内存大小:-Xms20M -Xmx20M
启动然后访问localhost:9090/heap,使得堆内存溢出
(5)关于dump下来的文件
一般dump下来的文件可以结合工具分析,这块后面讲
Person.java源码文件时Java这门高级开发语言,对程序员友好,方便我们开发。
javac编译器将Person.java源文件编译成Class文件【我们把这里的编译称为前期编译】,交给jvm运行,因为jvm只能认识class字节码文件。同时在不同的操作系统上安装对应版本的jDk,里面包含了各自屏蔽操作系统底层细节的jvm,这样同一份class文件就能运行在不同的操作系统平台之上,得益于jvm。这也是Write Once,Run Anywhere的原因所在。
最终jvm需要把字节码指令转换为机器码,可以理解为是0101这样的机器语言,这样才能运行在不同机器上,那么由字节码转变为机器码是谁做的,说白了就是谁来执行这些字节码指令的呢?这就是执行引擎

Interpreter,解析器逐条把字节码翻译成机器码并执行,跨平台的保证。
刚开始执行引擎只采用了解释执行,但是后来发现某些方法或者代码块被调用执行的特别频繁时,就会被这些代码认定为”热点代码“
Just-In-Time compilation(JIT)即时编译器先将节码编译成对应平台的可执行文件,运行速度快。即时编译器会把这些热点代码编译成与本地平台关联的机器码,并且进行各层的优化,保存到内存中
JVM采用的是混合模式,也就是解释+编译的方式,对于大部分不常用的代码,不需要浪费时间将其编译成机器码,只需要用到的时候再以解释的方式运行,对于小部分的热点代码,可以采取编译的方式追求更高的运行效率。
(1)HotSpot虚拟机里面内置了两个JIT:C1和C2
c1也称为client Compiler,适用于执行时间短或者对启动性能有要求的程序
C2也称为Server Compiler,适用于执行时间长或者对峰值性能有要求的程序
(2)java7开始,HotSpot会使用分层编译的方式
也就是会结合C1的启动性能优势和C2的峰值性能优势,热点方法会先被被C1编译,然后热点方法中的热点被C2再次编译
3.4.5 AOT和Graal VM
3.4.5.1 AOT
在java 9中,引入了AOT(Ahead-of-Time)编译器
即时编译器是在程序运行过程中,将字节码翻译成机器码,而AOT是在程序运行之前,将字节码转换为机器码
优势:这样不需要在运行过程中消耗计算机资源来进行即时编译
劣势:AOT编译无法得知程序运行时的信息,因此也无法进行基于类层次分析的完全虚方法内联,或者基于程序profile的投机性优化(并非硬性限制,我们可以通过限制运行范围,或者利用上一次运行程序profile来绕开这两个限制)
官网:https://www.oracle.com/tools/graalvm-enterprise-edition.html

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