java虚拟机学习之旅(1)——jps命令使用

我如今是一名本科大三学生,前面找实习的时候,面试官问了我虚拟机相关的知识,什么类加载机制,GC,内存模型之类的,jvm调优,jvm参数之类的当然没问,自我感觉答的还是比较好。但是后来面试官问我有没有用工具监测过java虚拟机,我就懵逼了。毫无疑问,这次面试挂掉了。面试官说的一句话我还记得,这些理论知识,只要看了博客都能说出来,关键是你要动手去做,去观察。于是在前段时间看了下工具,使用了一下JConsole,发现蛮有意思的,于是打算每天抽一点时间学点工具。

>>强大,10k+点赞的 SpringBoot 后台管理系统竟然出了详细教程!

jps

一、jps简介:

位置:很多java命令都位于jdk的JAVA_HOME/bin/目录下面,jps也同样位于这个目录,是java自带的一个命令,所以要使用就得先进入这个目录,如果配置了环境变量就不用这么烦琐了。jps(Java Virtual Machine Process Status Tool)是JDK 1.5提供的一个显示当前系统的java进程情况,及其id号的命令。但是jps只能查看当前用户的java进程,而不是系统中的所有java进程。

原理:jdk中的jps命令可以显示当前运行的java进程以及相关参数,它的实现机制如下:
java程序在启动以后,会在java.io.tmpdir指定的目录下,就是临时文件夹里,生成一个类似于hsperfdata_User的文件夹,这个文件夹里(在Linux中为/tmp/hsperfdata_{userName}/),有几个文件,名字就是java进程的pid,因此列出当前运行的java进程,只是把这个目录里的文件名列一下而已。 至于系统的参数什么,就可以解析这几个文件获得。但是在windows环境种我们如何找到这个文件呢?只需要如图下就可以了

二、jps使用

首先,我们先创建一个应用程序,

jps:直接jps而不加上任何参数输出的便是java进程以及相应的id号。

可以看见进程名TcpScan以及相应进程号87200.

jps -q:只显示pid,不显示class名称,jar文件名和传递给main 方法的参数

jsp -m:输出传递给main 方法的参数

jps -l:输出应用程序main class的完整package名 或者 应用程序的jar文件完整路径名

jps -v:输出传递给JVM的参数

三、jps失效(我没有遇到过,所以转载的)

jps可以查看当前哪些进程处于运行状态,如果我运行了一个web应用(使用tomcat、jboss、jetty等启动)的时候,我就可以使用jps查看启动情况。有时候我想知道这个应用的日志会输出到哪里,那么我们就可以使用jps -v查看进程的jva参数情况。由此可以看见这些工具对于我们项目的查找bug原因以及调试是有很大的帮助的。

但是有时候jps也会闹小情绪,有些明明已经启动了的进程,用jps查看却不存在该进程的id。那么是什么原因呢?之前jps简介已经介绍过, jps数据来源是一个临时文件。所以当该文件不存在或是无法读取时就会出现jps无法查看该进程号,jconsole无法监控等问题(jconsole、jvisualvm等工具的数据来源依然是这个临时文件)。分析得到原因有三:1、磁盘读写、目录权限问题 若该用户没有权限写该目录或是磁盘已满,则无法创建文件。或该文件已经生成,但用户没有读权限;2、临时文件丢失,被删除或是定期清理,对于linux机器,一般都会存在定时任务对临时文件夹进行清理,导致该目录被清空。这也是我第一次碰到该现象的原因。常用的可能定时删除临时目录的工具为crontab、redhat的tmpwatch、ubuntu的tmpreaper等等;3、java进程信息文件存储地址被设置,不在该目录下 上面我们在介绍时说默认会在/tmp/hsperfdata_userName目录保存进程信息,但由于以上1、2所述原因,可能导致该文件无法生成或是丢失,所以java启动时提供了参数(-Djava.io.tmpdir),可以对这个文件的位置进行设置,而jps、jconsole都只会从/tmp目录读取,而无法从设置后的目录读物信息,这是我第二次碰到该现象的原因。