JDK 下的java各个命令,他们都是什么语言来写的

JDK 是 Java 语言的软件开发工具包,没有它就无法编译 Java 程序。Java 开发人员肯定都知道 JDK 的 bin/ 目录下有“java”和“javac”这两个命令行工具,但并非所有程序员都了解过 JDK 的 bin/ 下其他命令行程序的作用。每逢 JDK 更新版本之时,bin/ 目录下命令行工具的数量和功能总会不知不觉地增加和增强。

在生产运行过程中最重要的工作莫过于监控与问题的处理,监控是预防问题产生很重要的手段。实现监控的手段非常多,有系统级别监控系统,也有许多监控小工具等等。JDK 中已提供了功能强大各种监控工具存放在 JDK 的 bin/ 目录下,bin/ 目录下如图

一、jps —— 虚拟机进程状况工具

jps(JVM Process Status Tool)用来显示本地的 java 进程,以及进程号,进程启动的路径等。

JDK 的很多小工具的名称都参考了 Unix 命令的命名方式,jps(JVM Process Status Tool)是其中的典型。除了名字像 Unix 的 ps 命令外,功能也和 ps 类似:可以列出正在运行的虚拟机进程,并显示虚拟机执行主类(Main Class,main() 函数所在的类)的名称,以及这些进程的本地虚拟机的唯一ID(LVMID,Local Virtual Machine Identifier)。虽然功能比较单一,但它是使用频率最高的 JDK 命令行工具,因为其他 JDK 工具大多需要输入它查询到的 LVMID 来确定要监控的是哪一个虚拟机进程。对于本地虚拟机进程来说,LVMID 与操作系统的进程 ID(PID,Process Identifier)是一致的,使用 Windows 的任务管理器或 Unix 的 ps 命令也可以查询到虚拟机进程的 LVMID,但如果使用了多个虚拟机进程,无法根据进程名称定位时,那就只能依赖 jps 命令显示主类的功能区才能区分了。


用法提示:

1
2
3
4
5
6
7
8
9
10
usage: jps [-help]
        jps [-q] [-mlvV] []
 
Definitions:
     :      [:]
     
-q    只输出LVMID,省略主类的名称    
-m    输出虚拟机进程启动时传递给主类的main()函数的参数    
-l    输出主类的全名,如果进程执行的是jar包,输出jar路径    
-v    输出虚拟机进程启动时JVM参数

1、显示运行中的Java进程:

1
2
3
[root@localhost ~] # jps
7563 Bootstrap
7349 Jps

2、显示进程 ID

1
2
3
[root@localhost ~] # jps -q
15779
7163

3、显示完整包名:

1
2
3
[root@localhost ~] # jps -l
7379 sun.tools.jps.Jps
7563 org.apache.catalina.startup.Bootstrap

4、输出Java进程的命令行输入参数:

1
2
3
[root@localhost ~] # jps -m
7395 Jps -m
7563 Bootstrap start

5、显示相应Java进程的完整的JVM参数:

1
2
3
[root@localhost ~] # jps -v
7484 Jps -Denv.class.path=.: /usr/local/jdk1 .7.0_79 /lib : /usr/local/jdk1 .7.0_79 /jre/lib : /usr/local/jdk1 .7.0_79 /lib/dt .jar: /usr/local/jdk1 .7.0_79 /lib/tools .jar -Dapplication.home= /usr/local/jdk1 .7.0_79 -Xms8m
7563 Bootstrap -Dnop -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed. dirs = /usr/local/tomcat7/endorsed  -Dcatalina.base= /usr/local/tomcat7  -Dcatalina.home= /usr/local/tomcat7  -Djava.io.tmpdir= /usr/local/tomcat7/temp

二、jinfo —— Java 配置信息工具

jinfo(Configuration Info for Java)的作用是实时地查看和调整虚拟机的各项参数。使用 jps 的命令的 -v 参数可以查看虚拟机启动时显示指定的参数列表,但如果想知道未被显示指定的参数的系统默认值,除了去找资料外,就只能使用 jinfo 的 -flag 选项进行查询了(如果只限于 JDK1.6 或以上版本的话,使用 java -XX:+PrintFlagsFinal 查看参数默认值也是一个很好的选择),jinfo 还可以使用 -sysprops 选项把虚拟机进程的System.getProperties() 的内容打印出来。这个命令在 JDK1.5 时期已经随着 Linux 版的 JDK 发布,当时只提供了信息查询的功能,JDK1.6 之后,jinfo 在 Windows 和 Linux 平台都有提供,并且加入了运行期修改参数的能力,可以使用 -flag[+|-]name 或 -flag name=valule 修改一部分运行期可写的虚拟机参数值。JDK1.6 中,jinfo 对于 Windows 平台的功能仍然有较大的限制,只提供了最基本的 -flag 选项。

jinfo 可观察运行中 java 程序的运行环境参数,参数包括 Java System 属性和 JVM 命令行参数;也可从 core 文件里面知道崩溃的 Java 应用程序的配置信息。

首先,通过 jps 命令获取 Java 程序 Bootstrap 的进程号 7015

1、显示所有与该进程相关的信息,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
[root@localhost ~] # jinfo 7563
Attaching to process ID 7563, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.79-b02
Java System Properties:
 
java.runtime.name = Java(TM) SE Runtime Environment
java.vm.version = 24.79-b02
sun.boot.library.path =  /usr/local/jdk1 .7.0_79 /jre/lib/amd64
shared.loader =
java.vendor.url = http: //java .oracle.com/
java.vm.vendor = Oracle Corporation
path.separator = :
file .encoding.pkg = sun.io
java.vm.name = Java HotSpot(TM) 64-Bit Server VM
tomcat.util.buf.StringCache.byte.enabled =  true
 
     ……(省略部分内容)
 
java.vendor = Oracle Corporation
catalina.base =  /usr/local/tomcat7
file .separator = /
nop =
java.vendor.url.bug = http: //bugreport .sun.com /bugreport/
common.loader = ${catalina.base} /lib ,${catalina.base} /lib/ *.jar,${catalina.home} /lib ,${catalina.home} /lib/ *.jar
sun.io.unicode.encoding = UnicodeLittle
sun.cpu.endian = little
package.access = sun.,org.apache.catalina.,org.apache.coyote.,org.apache.jasper.,org.apache.naming.resources.,org.apache.tomcat.
sun.cpu.isalist =
 
VM Flags:
 
-Dnop -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed. dirs = /usr/local/tomcat7/endorsed  -Dcatalina.base= /usr/local/tomcat7  -Dcatalina.home= /usr/local/tomcat7  -Djava.io.tmpdir= /usr/local/tomcat7/temp

2、并不是所有信息都是我们需要的,我们可以添加“-flag jvm参数 pid”显示相应 jvm 参数信息,例如:

1
2
3
4
5
6
7
8
[root@localhost ~] # jinfo -flag MaxPermSize 7563
-XX:MaxPermSize=85983232
[root@localhost ~] # jinfo -flag PermSize 7563
-XX:PermSize=21757952
[root@localhost ~] # jinfo -flag LargePageSizeInBytes 7563
-XX:LargePageSizeInBytes=0
[root@localhost ~] # jinfo -flag AllowUserSignalHandlers 7563
-XX:-AllowUserSignalHandlers

JVM 具体有哪些参数他们的意义都是什么我会在 tomcat 调优中进行介绍

三、jstat —— 虚拟机统计信息监控工具

jstat(JVM Statistics Monitoring Tool)是用于监控虚拟机各种运行状态信息的命令行工具。它利用了 JVM 内建的指令对 Java 应用程序的资源和性能进行实时的命令行的监控,包括了对 Heap size 和垃圾回收状况的监控等,可以显示本地或远程虚拟机进程中的类装载、内存、垃圾收集、JIT 编译等运行数据,在没有 GUI 图像界面,只提高了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。

用法提示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Usage: jstat -help|-options
        jstat -
 
Definitions:
  
   
           对于命令格式中的VMID与LVMID需要特别说明下:如果是本地虚拟机进程,
                 VMID和LVMID是一致的,如果是远程虚拟机进程,那VMID的格式应当是:
                 [protocol:][ // ] lvmid [@ hostname [:port] /servername ]
                 
          Number of samples between header lines.
       代表查询间隔,The following forms are allowed:
                     [ "ms" | "s" ]
                 Where  is an integer and the suffix specifies the  units  as
                 milliseconds( "ms" ) or seconds( "s" ). The default  units  are  "ms" .
          代表查询间隔和次数,Number of samples to take before terminating.
   -J      Pass  directly to the runtime system.

option代表这用户希望查询的虚拟机信息,主要分为3类:类装载、垃圾收集和运行期编译状况:

1
2
3
4
5
6
7
8
9
10
11
12
-class               监视类装载、卸载数量、总空间及类装载所耗费的时间,统计class loader行为信息   
-gc                  监视Java堆状况,包括Eden区、2个Survivor区、老年代、永久代等的容量,统计jdk gc时heap信息  
-gccapacity          监视内容与-gc基本相同,但输出主要关注Java 堆(heap)各个区域使用到的最大和最小空间   
-gcutil              监视内容与-gc基本相同, 但输出主要关注已使用空间占总空间的百分比     
-gccause             与-gcutil功能一样,但是会额外输出导致上一次GC产生的原因    
-gcnew               监视新生代GC的状况    
-gcnewcapacity       监视内容与-gcnew基本相同,输出主要关注使用到的最大和最小空间,新生代heap容量   
-gcold               监视老年代GC的状况    
-gcoldcapacity       监视内容与-gcold基本相同,输出主要关注使用到的最大和最小空间,老年区heap容量   
-gcpermcapacity      输出永久代使用到的最大和最小空间,permanent区heap容量   
-compiler            输出JIT编译器编译过的方法、耗时等信息    
-printcompilation    输出已经被JIT编译的方法

1、统计 gc heap 情况,此选项是较常用的一个选项:

1
2
3
[root@localhost ~] #  jstat -gcutil 7563
   S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT
   0.00  44.10  84.66  60.00  99.53    147    0.570     7    0.721    1.291

上面的命令没有刷新时间与刷新次数的参数,所以默认只打印出1行数据内容。

如果省略 interval 和 count 这两个参数,说明只查询一次。假设需要每 1000 毫秒查询一次进程 7563 垃圾收集状况,一共查询5次,那命令行如下

1
2
3
4
5
6
7
[root@localhost ~] #  jstat -gcutil 7563 1000 5
   S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT
   0.00  44.10  84.66  60.00  99.53    147    0.570     7    0.721    1.291
   0.00  44.10  84.66  60.00  99.53    147    0.570     7    0.721    1.291
   0.00  44.10  84.66  60.00  99.53    147    0.570     7    0.721    1.291
   0.00  44.10  84.66  60.00  99.53    147    0.570     7    0.721    1.291
   0.00  44.10  84.66  60.00  99.53    147    0.570     7    0.721    1.291

默认单位是ms,1000ms可以写成1s

1
2
3
4
5
6
7
8
9
10
11
#参数含义:
S0  — Heap上的 Survivor space 0 区已使用空间的百分比,里面都是空
S1  — Heap上的 Survivor space 1 区已使用空间的百分比,44.10%
E   — Heap上的 Eden space 区已使用空间的百分比,新生代 Eden 区使用了 84.66% 的空间
O   — Heap上的 Old space 区已使用空间的百分比,老年代 Old 区使用了 60.00% 的空间
P   — Perm space 区已使用空间的百分比,永久代 Permanent 区使用了99.53% 的空间
YGC — 从应用程序启动到采样时发生 Young GC 的次数,147 次
YGCT– 从应用程序启动到采样时 Young GC 所用的时间(单位秒),总耗时 0.570 秒
FGC — 从应用程序启动到采样时发生 Full GC 的次数,7 次
FGCT– 从应用程序启动到采样时 Full GC 所用的时间(单位秒) ,总耗时 0.721 秒
GCT — 从应用程序启动到采样时用于垃圾回收的总时间(单位秒),所有 gc 总耗时 1.291 秒

直接在控制台中使用 jstat 命令已然是一种常用的监控方式。

2、显示加载class的数量,及所占空间等信息:

1
2
3
[root@localhost ~] # jstat -class 7563
Loaded  Bytes  Unloaded  Bytes     Time
   2277  4700.2        0     0.0       1.65

3、显示VM实时编译的数量等信息:

1
2
3
[root@localhost ~] # jstat -compiler 7563
Compiled Failed Invalid   Time   FailedType FailedMethod
     1599      2       0    55.22          1 org /apache/tomcat/util/IntrospectionUtils  setProperty

4、显示三代 heap 情况

gccapacity 可以显示 JVM 内存中三代(young,old,perm)对象的使用和占用大小,如:PGCMN 显示的是最小 perm 的内存使用量,PGCMX 显示的是 perm 的内存最大使用量,PGC 是当前新生成的 perm 内存占用量,PC 是但前 perm 内存占用量。其他的可以根据这个类推, OC 是 old 内存的占用大小。

1
2
3
[root@localhost ~] # jstat -gccapacity 7563
  NGCMN    NGCMX     NGC     S0C   S1C       EC      OGCMN      OGCMX       OGC         OC      PGCMN    PGCMX     PGC       PC     YGC    FGC
  10688.0 171328.0  38464.0 3840.0 3840.0  30784.0    21440.0   342720.0    76820.0    76820.0  21248.0  83968.0  50368.0  50368.0    154     7

四、jstatd —— Java 后台统计监测

jstatd(Java Statistics Monitoring Daemon)是一个基于提供远程监控接口的 RMI(Remove Method Invocation,远程方法调用)的服务器程序,它用于监控基于 HotSpot 的 JVM 中资源的创建及销毁过程中资源占用情况,它是一个 Daemon 程序,要保证远程监控软件连接到本地的话需要 jstatd 始终保持运行,默认端口是 1099。

首先,我们可以在用户目录下的任何地方(比如说:用户根目录,或者是 JDK 根目录)新建一个名称为 my.policy 的文件,文件内容如下:

1
2
3
grant codebase  "file:${java.home}/../lib/tools.jar"  {  
  permission java.security.AllPermission;  
};

这是安全策略文件,因为 jdk 对 jvm 做了 jaas 的安全检测,所以我们必须设置一些策略,使得 jstatd 被允许作网络操作。

运行如下命令,启动jstatd服务

1
jstatd -J -Djava.security.policy= /usr/local/jdk1 .7.0_79 /my .policy

记住 my.policy 文件必须为绝对路径,防止出现 java.security.AccessControlException: access denied (java.util.PropertyPermission java.rmi.server.ignoreSubClasses write) 错误。 

如果需要RMI 日志功能的话,还可以在启动参数中加入 -J-Djava.rmi.server.logCalls=true。

五、jmap —— Java内存映像工具

jmap(Memory Map for Java)命令可以直接观察运行中的 JVM 物理内存的占用情况,可用于生产堆转储快照(一般称为 heapdump 或 dump 文件)。如果不使用 jmap 命令,要向获取 Java 堆转储快照还有一些比较”暴力“的手段:譬如 -XX:+HeapDumpOnOutOfMemoryError 参数,可以让虚拟机在 OOM 异常出现之后自动生生成 dump 文件,通过 -XX:+HeapDumpOnCtrlBreak 参数则可以使用 [Ctrl]+[Break] 键让虚拟机生成 dump 文件,又或者在 Linux 系统下通过 Kill -3 命令发送进程退出信号”恐吓“一下虚拟机,也能拿到 dump 文件。

jmap 的作用并不仅仅是为了获取 dump 文件,它还可以查询 finalize 执行队列,Java 堆和永久代的详细信息,如空间使用率、当前用的是那种收集器等。除了生成 dump 文件的 -dump 选项和用于查看每个类的实例、空间占用统计的 -histo 选项,其余选项只能在 Linux/Solaris 下使用







你可能感兴趣的:(Java)