java命令启动java应用程序。它通过启动Java运行时环境(JRE)、加载指定的类并调用该类的main()方法来实现这一点。
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html#BGBCIEFC
javap是 Java class文件分解器,可以反编译,也可以查看java编译器生成的字节码。用于分解class文件。
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/javap.html#BEHHDJGA
javac 是java语言编程编译器。全称java compiler。javac工具读由java语言编写的类和接口的定义,并将它们编译成字节代码的class文件。javac 可以隐式编译一些没有在命令行中提及的源文件。用 -verbose 选项可跟踪自动编译。当编译源文件时,编译器常常需要它还没有识别出的类型的有关信息。对于源文件中使用、扩展或实现的每个类或接口,编译器都需要其类型信息。这包括在源文件中没有明确提及、但通过继承提供信息的类和接口。
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/javac.html#BHCBDCJI
用法: javac
其中, 可能的选项包括:
-g 生成所有调试信息
-g:none 不生成任何调试信息
-g:{lines,vars,source} 只生成某些调试信息
-nowarn 不生成任何警告
-verbose 输出有关编译器正在执行的操作的消息
-deprecation 输出使用已过时的 API 的源位置
-classpath <路径> 指定查找用户类文件和注释处理程序的位置
-cp <路径> 指定查找用户类文件和注释处理程序的位置
-sourcepath <路径> 指定查找输入源文件的位置
-bootclasspath <路径> 覆盖引导类文件的位置
-extdirs <目录> 覆盖所安装扩展的位置
-endorseddirs <目录> 覆盖签名的标准路径的位置
-proc:{none,only} 控制是否执行注释处理和/或编译。
-processor [,,...] 要运行的注释处理程序的名称; 绕过默认的搜索进程
-processorpath <路径> 指定查找注释处理程序的位置
-d <目录> 指定放置生成的类文件的位置
-s <目录> 指定放置生成的源文件的位置
-implicit:{none,class} 指定是否为隐式引用文件生成类文件
-encoding <编码> 指定源文件使用的字符编码
-source <发行版> 提供与指定发行版的源兼容性
-target <发行版> 生成特定 VM 版本的类文件
-version 版本信息
-help 输出标准选项的提要
-A关键字[=值] 传递给注释处理程序的选项
-X 输出非标准选项的提要
-J<标记> 直接将 <标记> 传递给运行时系统
-Werror 出现警告时终止编译
@<文件名> 从文件读取选项和文件名(多个Java文件写在此文件中)
jps(Java Virtual Machine Process Status Tool)是java提供的一个显示当前所有java进程pid的命令,适合在linux/unix平台上简单察看当前java进程的一些简单情况。
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jps.html#CHDCGECD
jinfo是java虚拟机自带的Java配置信息工具,可以实时地查看和调整虚拟机的各项参数。
在很多情况下,Java应用程序不会指定所有的Java虚拟机参数。而此时,开发人员可能不知道某一个具体的Java虚拟机参数的默认值。在这种情况下,可能需要通过查找文档获取某个参数的默认值。这个查找过程可能是非常艰难的。但有了 jinfo工具,开发人员可以很方便地找到Java虚拟机参数的当前值。
jinfo不仅可以查看运行时某一个Java虚拟机参数的实际取值, 甚至可以在运行时修改部分参 数,并使之立即生效。 但是,并非所有参数都支持动态修改。参数只有被标记 manageable的flag可以被实时修改。其实,这个修改能力是 极其有限的。
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jinfo.html#BCGEBFDD
Jstat是java虚拟机统计信息工具,利用JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控。
主要利用JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heap size和垃圾回收状况的监控。
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html#BEHHGFAE
jstat -
option:参数选项
-
jstat -options
jstack是java虚拟机自带的一种堆栈跟踪工具,它用于打印出给定的java进程ID、core file、远程调试服务的Java堆栈信息。
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstack.html#BABGJDIF
jstack [ option ] pid // 打印某个进程的堆栈信息 (最常用)
jstack [ option ] executable core
jstack [ option ] [server-id@]remote-hostname-or-IP
option参数如下:
使用jstack排查死锁问题
jstack -l pid | grep "deadlock"
主要是生成java进程当前(当前指的是执行命令的时刻)内存堆转储快照,生成的快照经常用于分析内存溢出或者内存泄漏相关的问题。
除了生成内存快照,还可以有如下作用:
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jmap.html#CEGCECJB
jmap [option] (最常用)
(to connect to running process)
jmap [option]
(to connect to a core file)
jmap [option] [server_id@]
(to connect to remote debug server)
jmap -dump:live,format=b,file=/path-you-want-to-save/java-heap-dump.hprof pid
Java堆和方法区的详细信息、内存空间使用率、当前用的是哪种收集器:
jmap -heap pid
jhat命令与jmap命令搭配使用,用于分析jmap生成的heap dump文件(堆转储快照)。jhat内置了一个微型的HTTP/HTML服务器,对生成的dump文件分析后,可以在浏览器中查看分析结果。
注:jhat命令在JDK9、JDK10中已经被删除,官方建议用VisualVM代替。
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jhat.html#CIHHJAGE
jhat [-stack ] [-refs ] [-port ] [-baseline ] [-debug ] [-version] [-h|-help]
top // 假设找到进程号是98344
方案1
ps -Lp #pid cu // ps -Lp 98344 cu
ps -Lp #pid cu --sort -pcpu // 按CPU倒序排序 +pcpu(按cpu升序排序)
ps -Lp #pid cu --sort -pmem // 按内存倒序排序
ps -Lp #pid cu | sort -rnk 3 // 按照第三列倒序排序
ps -Lp #pid cu | sort -rnk 3 | head -n 1 // 排序展示第一条
方案2
top -Hp pid // top -Hp 98344
printf '%x\n' #threadId // printf '%x\n' 98345 -> 18029
jstack #pid | grep -A 10 "nid=0x<十六进制码>" // jstack 10 | grep -A 10 "nid=0x18029"
free是查看内存使用情况,包括物理内存、交换内存(swap)和内核缓冲区内存。
free -h -s 3表示每隔三秒输出一次内存情况,命令如下:
交换空间(swap space)
swap space 是磁盘上的一块区域,当系统物理内存吃紧时,Linux 会将内存中不常访问的数据保存到 swap 上,这样系统就有更多的物理内存为各个进程服务,而当系统需要访问 swap 上存储的内容时,再将 swap 上的数据加载到内存中,这就是常说的换出和换入。
交换空间可以在一定程度上缓解内存不足的情况,但是它需要读写磁盘数据,所以性能不是很高。
vmstat(VirtualMeomoryStatistics,虚拟内存统计)是Linux中监控内存的常用工具,可对操作系统的虚拟内存、进程、CPU等的整体情况进行监视,推荐使用。
procs模块
memory模块
swap模块
注意:一般情况下si、so的值都为0,如果si、so的值长期不为0,则说明系统内存不足,需要增加系统内存
io模块
注意:如果bi+bo的值过大,且wa值较大,则表示系统磁盘IO瓶颈。
system 模块
例如在apache和nginx这种web服务器中,我们一般做性能测试时会进行几千并发甚至几万并发的测试,选择web服务器的进程可以由进程或者线程的峰值一直下调,压测,直到cs到一个比较小的值,这个进程和线程数就是比较合适的值了。
系统调用也是,每次调用系统函数,我们的代码就会进入内核空间,导致上下文切换,这个是很耗资源,也要尽量避免频繁调用系统函数。
上下文切换次数过多表示你的CPU大部分浪费在上下文切换,导致CPU干正经事的时间少了,CPU没有充分利用,是不可取的。
注意:这两个值越大,则由内核消耗的CPU就越多。
CPU模块
sar和free类似sar -r 3每隔三秒输出一次内存信息:
通过sar -u 3可以查看CUP总体消耗占比:
在以上的显示当中,主要看%iowait和%idle:
在Linux内核的操作系统中,进程是根据虚拟运行时间(由进程优先级、nice值加上实际占用的CPU时间进行动态计算得出)进行动态调度的。
在执行进程时,需要从用户态转换到内核态,用户空间不能直接操作内核空间的函数。
通常要利用系统调用来完成进程调度,而用户空间到内核空间的转换通常是通过软中断来完成的。例如要进行磁盘操作,用户态需要通过系统调用内核的磁盘操作指令,所以CPU消耗的时间被切分成用户态CPU消耗、系统(内核) CPU 消耗,以及磁盘操作 CPU 消耗。
执行进程时,需要经过一系列的操作,进程首先在用户态执行,在执行过程中会进行进程优先级的调整(nice),通过系统调用到内核,再通过内核调用,硬中断、软中断,让硬件执行任务。
执行完成之后,再从内核态返回给系统调用,最后系统调用将结果返回给用户态的进程。
top可以查看CPU总体消耗,包括分项消耗,如User,System,Idle,nice等。
多核CPU,进入top视图1,可以看到各CPU的负载情况。
第一行:15:24:11 up 8 days, 7:52, 1 user, load average: 5.73, 6.85, 7.33:
第二行:Tasks: 17 total, 1 running, 16 sleeping, 0 stopped, 0 zombie:
第三行:%Cpu(s): 13.9 us, 9.2 sy, 0.0 ni, 76.1 id, 0.1 wa, 0.0 hi, 0.1 si, 0.7 st:
第四和第五行表示内存和swap区域的使用情况
第七行
du -sh命令是查看磁盘已使用空间的情况,这里的“已使用的磁盘空间”意思是指定的文件下的整个文件层次结构所使用的空间,在没给定参数的情况下,du报告当前目录所使用的磁盘空间。
其实就是显示文件或目录所占用的磁盘空间的情况:
du的详细信息可以通过 man du查看。
通过iostat -x 1 3可以看到磁盘详细读写情况,没隔一秒输出一次一共输出3次,当看到I/O等待时间所占CPU时间的比重很高的时候,首先要检查的就是机器是否正在大量使用交换空间,同时关注iowait占比cpu的消耗是否很大,如果大说明磁盘存在大的瓶颈,同时关注await,表示磁盘的响应时间以便小于5ms:
avg-cpu表示总体cpu使用情况统计信息,对于多核cpu,这里为所有cpu的平均值:
Device表示设备信息
!! iostat -xmd 1 3:新增m选项可以在输出是使用M为单位。
一般先通过iostat查看是否存在io瓶颈,再使用iotop命令来定位那个进程最耗费IO:
通过iotop -p pid可以查看单个进程的IO情况:
如查看java的进程的pid,ps -ef | grep java:
如查看java进程的数量,ps -ef | grep java| wc -l:
查看线程是否存在死锁,jstack -l pid:
ps -efL | grep [PID] | wc -l,如:
查看具体有哪些线程用ps -Lp [pid] cu:
find / -type f -name “*.log” | xargs grep “ERROR”,这个在排查问题过程中比较有用:
java -jar -Xms128m -Xmx1024m -Xss512k -XX:PermSize=128m -XX:MaxPermSize=64m -XX:NewSize=64m -XX:MaxNewSize=256m arthas-demo.jar,如: