【JVM命令系列】javap
命令基本概述
javap是JDK自带的反汇编器,可以查看java编译器为我们生成的字节码。通过它,可以对照源代码和字节码,从而了解很多编译器内部的工作。可以在命令行窗口先用javap -help看下javap工具支持的选项:C:\>javap -help
C:\>javap -help Usage: javap <options> <classes>... where options include: -c 输出类中各方法的未解析的代码,即构成java字节码的指令 -classpath <pathlist> 指定javap用来查找类的路径。目录用:分隔 -extdirs <dirs> 覆盖搜索安装方式扩展的位置,扩展的缺省位置为jre/lib/ext -help 输出帮助信息 -J<flag> 直接将flag传给运行时系统 -l 输出行及局部变量表 -public 只显示public类及成员 -protected 只显示protected和public类及成员。 -package 只显示包、protected和public类及成员,,这是缺省设置 -private 显示所有的类和成员 -s 输出内部类型签名 -bootclasspath <pathlist> 指定加载自举类所用的路径,如jre/lib/rt.jar或i18n.jar -verbose 打印堆栈大小、各方法的locals及args参数,以及class文件的编译版本
参数说明
平时一般用-c选项用得比较多,该命令用于列出每个方法所执行的JVM指令,并显示每个方法的字节码的实际作用。可以写个HelloWorld的程序来测试一下该命令。
public class HelloWorld {
public static void main(String[] args){
System.out.println("Hello World!");
}
}
$ javap -cHelloWorld在将该java类编译生成HelloWorld.class文件后,即可通过javap进行具体的反编译分析。如:
Compiled from "HelloWorld.java"
public class HelloWorld extends java.lang.Object{
public HelloWorld();
Code:
: aload_0
: invokespecial #; //Method java/lang/Object."<init>":()V
: return
public static void main(java.lang.String[]);
Code:
: getstatic #; //Field java/lang/System.out:Ljava/io/PrintStream;
: ldc #; //String Hello World!
: invokevirtual #; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
: return
}
0: getstatic #2; //Fieldjava/lang/System.out:Ljava/io/PrintStream;为了能够更清晰的了解javap反编译生成的字节码,下面来分析main方法中的指令,vcb用于转换Java语言中的代码行System.out.println("HelloWorld!");
最初始的整数表示方法中指令的偏移量,因此第一个指令是从0开始的。它表示的是从java.lang.system对象的out字段中检索PrintStream对象,getstatic指令即是将该静态域压缩并放到操作数栈中。按下来的指令则是引用一个地址,在当前情况下,指的是“#2;//Field java/lang/System.out:Ljava/io/PrintStream;”。在此你将会发现该域信息并没有直接嵌入进来。相反它是通过类似java类中的其它常量一样,该域信息被存储在一个共享池中。采用该常量池的方式能够减小字节码指令的长度。这也就是为什么指令中仅仅保存常量池的地址索引,而非所有的信息。在本示例中,域信息被存放在常量池中标识有#2的位置。
3: ldc #3; //String Hello World!
其实分析完第一条指令后,将非常容易的猜测到第二条指令的具体含义了。ldc(load constant)指令用于将HelloWorld!字符串压入至栈中。
5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
该指令将调用println方法,它将从操作栈中弹出两个参数。千成别忘记了象println这样的实例方法其实是包含了两个参数的,一个是字符串,另一个是隐式的this索引。
上面的minor version: 0和majorversion: 49就是编译Worke.class时使用的jdk编译版本号。
但是它并不是我们所熟悉的jdk版本号(比如jdk1.5)。
不过我们可以把从 JDK 1.1 到 JDK 1.7 编译器编译出的 class 的默认minor.major version 汇总下就知道对应关系了。
|
JDK 编译器版本 |
target 参数 |
十六进制 minor.major |
十进制 minor.major |
|
jdk1.1.8 |
不能带 target 参数 |
00 03 00 2D |
45.3 |
|
jdk1.2.2 |
不带(默认为 -target 1.1) |
00 03 00 2D |
45.3 |
|
jdk1.2.2 |
-target 1.2 |
00 00 00 2E |
46.0 |
|
jdk1.3.1_19 |
不带(默认为 -target 1.1) |
00 03 00 2D |
45.3 |
|
jdk1.3.1_19 |
-target 1.3 |
00 00 00 2F |
47.0 |
|
j2sdk1.4.2_10 |
不带(默认为 -target 1.2) |
00 00 00 2E |
46.0 |
|
j2sdk1.4.2_10 |
-target 1.4 |
00 00 00 30 |
48.0 |
|
jdk1.5.0_11 |
不带(默认为 -target 1.5) |
00 00 00 31 |
49.0 |
|
jdk1.5.0_11 |
-target 1.4 -source 1.4 |
00 00 00 30 |
48.0 |
|
jdk1.6.0_01 |
不带(默认为 -target 1.6) |
00 00 00 32 |
50.0 |
|
jdk1.6.0_01 |
-target 1.5 |
00 00 00 31 |
49.0 |
|
jdk1.6.0_01 |
-target 1.4 -source 1.4 |
00 00 00 30 |
48.0 |
|
jdk1.7.0 |
不带(默认为 -target 1.6) |
00 00 00 32 |
50.0 |
|
jdk1.7.0 |
-target 1.7 |
00 00 00 33 |
51.0 |
|
jdk1.7.0 |
-target 1.4 -source 1.4 |
00 00 00 30 |
48.0 |
|
Apache Harmony 5.0M3 |
不带(默认为 -target 1.2) |
00 00 00 2E |
46.0 |
|
Apache Harmony 5.0M3 |
-target 1.4 |
00 00 00 30 |
48.0 |
【JVM命令系列】javap的更多相关文章
- 【JVM命令系列】jstat
命令基本概述 Jstat是JDK自带的一个轻量级小工具.全称"Java Virtual Machine statistics monitoring tool",它位于java的bi ...
- 【JVM命令系列】jstack
jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使 ...
- 【JVM命令系列】jmap
命令基本概述 Jmap是一个可以输出所有内存中对象的工具,甚至可以将VM 中的heap,以二进制输出成文本.打印出某个java进程(使用pid)内存内的,所有'对象'的情况(如:产生那些对象,及其数量 ...
- JVM基础系列第15讲:JDK性能监控命令
查看虚拟机进程:jps 命令 jps 命令可以列出所有的 Java 进程.如果 jps 不加任何参数,可以列出 Java 程序的进程 ID 以及 Main 函数短名称,如下所示. $ jps 6540 ...
- JVM基础系列第5讲:字节码文件结构
温馨提示:此篇文章长达两万字,图片50多张,内容非常多,建议收藏后再看. 前面我们说到 Java 虚拟机使用字节码实现了跨平台的愿景,无论什么系统,我们都可以使用 Java 虚拟机解释执行字节码文件. ...
- JVM基础系列第14讲:JVM参数之GC日志配置
说到 Java 虚拟机,不得不提的就是 Java 虚拟机的 GC(Garbage Collection)日志.而对于 GC 日志,我们不仅要学会看懂,而且要学会如何设置对应的 GC 日志参数.今天就让 ...
- JVM基础系列第13讲:JVM参数之追踪类信息
我们都知道 JVM 在启动的时候会去加载类信息,那么我们怎么得知他加载了哪些类,又卸载了哪些类呢?我们这一节就来介绍四个 JVM 参数,使用它们我们就可以清晰地知道 JVM 的类加载信息. 为了方便演 ...
- JVM基础系列第11讲:JVM参数之堆栈空间配置
JVM 中最重要的一部分就是堆空间了,基本上大多数的线上 JVM 问题都是因为堆空间造成的 OutOfMemoryError.因此掌握 JVM 关于堆空间的参数配置对于排查线上问题非常重要. tips ...
- JVM基础系列第10讲:垃圾回收的几种类型
我们经常会听到许多垃圾回收的术语,例如:Minor GC.Major GC.Young GC.Old GC.Full GC.Stop-The-World 等.但这些 GC 术语到底指的是什么,它们之间 ...
随机推荐
- 简单易学的SSM(Spring+SpringMVC+MyBatis)整合
SSM(Spring+SpringMVC+MyBatis)的整合: 具体执行过程:1.用户在页面向后台发送一个请求 2.请求由DispatcherServlet 前端控制器拦截交给SpringMVC管 ...
- UI设计基础知识和JavaScript
[PS基础案例] 人物修图.调整画布大小,建立3个图层,并列放到画布中,用修补工具修掉中间的人物,再用橡皮章盖掉边缘的人物,然后扣出人物,放上新的蓝天,用橡皮擦调整透明度,擦掉水天交接的地方,然后调整 ...
- JS基础-----JS中的分支结构及循环结构
[分支结构] 一.if-else结构 1.结构的写法:if(判断条件){ //条件为true时,执行if的{} }else{ //条件为false时,执行else的{} } 2.注意事项 ①else语 ...
- chrome开发工具指南(三)
Security 面板 使用 Security Overview 可以立即查看当前页面是否安全. 检查各个源以查看连接和证书详情(安全源)或找出具体哪些请求未受保护(非安全源). Security O ...
- 使用Sidecar将Node.js引入Spring Cloud
网上看到的一篇文章,觉得写得挺好,现转载于此,以方便需要的网友查阅. 该文章介绍了非JAVA语言提供的应用集成到Spring Cloud的这样一个实现,以便我们使用其他语言作为参考. 感谢原作者分享, ...
- Linux_window与linux之间文件互传,上传下载
window与linux之间文件互传 运行环境:Centos os7 + win8.1 +putty putty:是一个Telnet,ssh,rlogin,纯tcp以及串行接口连接软件,由于linux ...
- Push or Pull?
采用Pull模型还是Push模型是很多中间件都会面临的一个问题.消息中间件.配置管理中心等都会需要考虑Client和Server之间的交互采用哪种模型: 服务端主动推送数据给客户端? 客户端主动从服务 ...
- Java零碎知识点
█ 举个例子:Iterator iter = map.entrySet().iterator(); xx.yy() ,表示一个xx对象的yy方法 ,xx.yy().zz()中 xx.yy()返回 ...
- 团队作业4——第一次项目冲刺(Alpha版本) Day1
1.开站立式会议: 2.Leangoo任务分解图: 3.开会讨论的结果,任务分派 队员 今日进展 明日安排 林燕 调查产品的市场需求,学习微信开发 完善逻辑架构框架 王李焕 结合实际分析系统设计思路, ...
- 201521123013 《Java程序设计》第14周学习总结
1. 本周学习总结 2. 书面作业 Q1. MySQL数据库基本操作 1.1 建立数据库,将自己的姓名.学号作为一条记录插入.(截图,需出现自己的学号.姓名) 1.2 在自己建立的数据库上执行常见SQ ...