简介: 我们不懂jvm调优也不影响我们敲代码,也不影响我们写业务,我们在简单的项目中也遇不到。但是他却是你面试失败的重要原因,学习Java开发,又怎么可以不了解Jvm的工作原理和简单调优呢, 不知道调优不会影响你成为一个程序员,但是会影响你成为一个优秀的程序员 。
JVM参数类型
(1)基本参数
所有jvm都实现这些参数,一般都不会变
1. -help
2. -server -client
3. -version -showversion
4. -cp -classpath
(2)X参数
默认jvm实现这些参数的功能,又比较小的可能会变
1.-Xint : 解释执行
2.-Xcomp:第一次使用就编译成本地代码
3.-Xmixed: 混合模式,JVM自己来决定是否编译成本地代码
(3)XX参数
不同的jvm会有所不同
1、Boolean类型
格式: -XX:[+-]<name> 表示启用或者禁用name属性
比如: -XX:+UseConcMarkSweepGC
-XX:UseG1GC
2、非Boolean类型
格式: -XX:<name>=<value> 表示name属性的值是value
比如:-XX:MaxGCPauseMillis=500
XX:GCTimeRatio=19
3、 -Xmx -Xms
不是X参数,而是XX参数
-Xms等价于-XX:InitialHeapSize
-Xmx等价于-XX:MaxHeapSize
在我们基本调优中,主要用的就是XX参数
-XX:+PrintFlagsInitial
-XX:+PrintFlagsFinal
-XX:+UnlockExperimentalVMOptions //解锁实验参数
-XX:+UnlockDiagnosticVMOptions //解锁诊断参数
-XX:+PrintCommandLineFlags //打印命令行参数
1. java -XX:+PrintFlagsFinal -version 查看XX参数
JVM常用工具
java开发工具规范
**(1)jps 列出目标系统上已检测的JVM **
1. jps //查看java进程
2. jps -l //查看完整类名
**(2)jmap 打印指定java进程的内存使用详细信息 **
-heap pud 打印java堆信息
-clstats pid 连接到正在运行的进程并打印Java堆的类加载器统计信息。
-finalizerinfo pid 连接到正在运行的进程,并在等待完成的对象上打印信息。
-histo pid 连接到正在运行的进程,并打印Java对象堆的直方图。如果live指定了子选项,则它仅计算活动对象。
-dump:dump_options pid 连接到正在运行的进程并转储Java堆。
该dump_options包括:
live 指定时,仅转储活动对象;如果未指定,则转储堆中的所有对象。
format=b 以hprof二进制格式转储Java堆
file=filename 将堆转储到filename
实例:jmap -dump:live,format=b,file=heap.hprof pid
我们在使用时可以会报错, 类似于 jmap 这些 JDK 工具依赖于 Linux 的 PTRACE_ATTACH,而是 Docker 自 1.10 在默认的 seccomp 配置文件中禁用了 ptrace。 所以在生成容器时我们要
docker run --cap-add=SYS_PTRACE ... 这样我们就可以使用jmap命令了
jmap的使用可以让我们有效的分析jvm内存使用情况,借助工具可以快速定位内存溢出或者泄露。
我们可以使用jdk自带的jvisualvm进行分析和MemoryAnalyzer工具
(3) jstack为指定的Java进程打印Java线程的Java堆栈跟踪
线程的5中状态:
1.新建(NEW):新创建了一个线程对象。
2.可运行(RUNNABLE):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权 。
3.运行(RUNNING):可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,执行程序代码。
4.阻塞(BLOCKED):阻塞状态是指线程因为某种原因放弃了cpu 使用权,也即让出了cpu timeslice,暂时停止运行
5.死亡(DEAD):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。
![](http://dsvip1.vip/jvm8.png)
当我们的程序中出现死循环或者死锁时,我们的cpu就是飙升,这是我们就用到了jstack命令查找问题
()内为变量
1.top //查找到我们所有进程,定位到进程pid
2.top -p (pid) -H //打印进程内所有线程,找到具体是那些线程
3.jstack (pid) > a.txt //将java进程的堆栈跟踪信息打印到a.txt文件
4.printf "%x" (pid) //我们a.txt文件的pid是16进制的,打印对应pid的16进制