用惯了各种方便的ide之后,我们时常忘了程序它本来的面貌,虽然也没有多大关系,但是如果想探究具体细节,用命令行执行代码也能加深理解
环境相关
- 当在机器上安装了jdk之后,需要配置一些环境变量,例如我们的jdk安装在了/u01/soft/jdk1.6目录下面
EXPORT JAVA_HOME=/u01/soft/jdk1.6 EXPORT PATH=$PATH:$JAVA_HOME/bin
其中环境变量可能通过echo查看,例如: echo $JAVA_HOME
- 在java的bin目录下面有一些常用的可执行工具,如javac, java, jar, javap, jps, jstat, jmap, jstack等
/u01/soft/jdk1.6/bin/jps $JAVA_HOME/bin/jps jps
如果没有配置环境变量,就只能用第一种方式执行了
编译相关
- 把源文件(.java)编译成二进制(.class)的时候,我们用的命令是javac,如果源文件里面引用了第三方的jar,则在编译的时候需要把jar加入到classpath变量中去
cp=.:/u01/project/commons-lang-2.6.jar /u01/soft/jdk1.6/bin/javac -cp $cp com/ali/Test.java
如果没有引入第三方的jar,则可以不需要cp参数
- 通常程序依赖的第三方jar比较多,我们会把所有依赖放在一个目录中,但是classpath中是无法识别目录的,只能把每个jar的相对路径用冒号(windows中是分号)隔开
cp=. for jar in `find /u01/project/lib -name *.jar` do cp=$cp:$jar done javac -cp $cp com/ali/Test.java
还可以借助其它工具来拼接cp参数
- 用javap还可以反编译生成好的.class文件
javap com/ali/Test.class javap -v com/ali/Test.class
反编译可能解析出.class文件中的许多有用信息,可能通过这些信息还原出源文件
执行相关
- 程序执行用java命令,一般也是需要带上classpath参数的
java -cp $cp com.ali.Test java -cp $cp com.ali.Test param1 java -Xmx1G -Xss1M -cp $cp com.ali.Test param1 java -Xbootclasspath/a:/u01/project/lib/lombok.jar com.ali.Test
用java执行的时候,在java关键字后面带虚拟机参数,在具体执行的类(全路径)后面带程序参数,具体虚拟机参数可以通过java --help查看,原来及用法可以参考官方文档
- 可以通过参数实现特殊功能,比如增加系统变量,debug模式启动,增加agent等
java -DsysProp=test com.ali.Test java -agentlib:jdwp=transport=dt_socket,suspend=y,address=localhost:50470 com.ali.Test java -javaagent:/u01/project/lib/java-tracer.jar=compress com.ali.Test
在java进程运行的时候,可能通过ps -aux|grep java查看启动参数,java提供了动态加载非classpath中的jar的机制,如果所有jar扁平放在cp参数中会导致命令行过长,因此可以通过-D参数来指定lib目录,让程序动态来加载jar,这个是-D参数的一个扩展应用
监控相关
- jps查看进程,jstack查看线程栈,jmap拓扑内存,jstat 查看内存使用情况
jsp jstack 1234 jstat -gcutil 1234 1000 1000 jmap -histo:live 1234
复杂的应用可以见官方文档
- 还可以通过jvm的attach机制,把一个agent attach到正在运行中的进程上,“侵入”进程,做一些特殊的用途