zoukankan      html  css  js  c++  java
  • [置顶] Java字节码文件剖析

    Java为什么能够支持跨平台,其实关键就是在于其*.class字节码文件,因为*.class字节码文件有一个统一标准的规范,里面是JVM运行的时需要的相关指令,各家的JVM必须能够解释编译执行标准字节码文件,因此Java是一种跨平台语言,再想想C++/C等语言为什么不是跨平台的,就是因为其源文件经过编译后生成的就是针对特定机器的汇编代码

    字节码文件解析

    在解析之前最好下载一个工具方便查看(Bytecode viewer),当然也可以不用下载,直接使用JDK自带的命令如javap –c –s –l –verbose (字节码文件去掉扩展名)

    一个简单的程序

    public class Test {
    private static final int MAX_COUNT=1000;
    private static int count=0;
    public int bar() throws Exception{
    	if(++count>=MAX_COUNT){
    		count=0;
    		throw new Exception("count overflow");
    	}
    	return count;
    }
    }

    运行工具软件查看得下图:

    看到了吧,一个字节码文件由6部份组成,先看第一部份General Information,这一部份中说明了JDK使用的版本号Major version=51表示使用的是JDK 7,Minor version=0表示的是次版本号,这也限制了运行此字节码文件需要的最低JDK版本号,不信你可以试试下面这条语句,其实就是从字节码文件中获取到class的版本号

    System.out.println(System.getProperty("java.class.version"));

    下面是constant pool=35,常量池中存放着类中定义的所有常量,大致包括类名,方法名,特征符以及字符串等,Access flag=0x0021[public]表识该类的访问权限,This class=cp_info_#1<Test>其中cp是const pool的缩写,表示这个类的信息保存在了1号常量池中,下面讲到constant pool时再说,super class=cp_info_#3也表示同一个意思,Interface count=0表示类没有实现接口,Fields count=2说明类中定义了两个成员变量,不信你看看刚才的源文件是不是有两个变量,Methods count=3表明类中定义的方法数是3(clinit对静态变量进行赋值由JVM调用, init为类的构造函数 bar用户自定义函数),Attribute count=1表示是类格式属性看看常量池如下,不截图了

    [01] CONSTANT_Class_info
    	Classname:cp_info_#2<Test>
    表示Classname存放在2号常量池中
    [02] CONSTANT_Utf8_info
    	Length of byte array :4
    	Length of string:4
    	String: Test
    

    表示类名是Test,长度是4,占用4个字节

    其他类似,看看方法Method里的<init>即构造函数

    Name: cp_info_#17<<init>>
    Desciptor:cp_info_#11<()V>
    Access flags:0x0001[public]
    

    Name的信息在常量池cp_info_#17中

    Length of byte array:6
    Length of string:6
    String:<init>
    

    从中可以看出其定义了字节码中类的构造函数的方法名,Descriptor描述的是函数的返回类型

    Length of byte array:3
    Length of string:3
    String:()V
    

    描述了函数的返回类型即为void类型,这个Access flags就不用多说了吧,表示的是函数访问权限,缺省构造器中的“指令是面向过程的汇编语言。aload_0说的是把对象的引用保存到JVM的0号局部变量,并且把它压入栈。invokespecial #1这条命令是调用java.lang.Object中的构造(这些信息保存在1号常量项里,好处是减少字节码的长度),return是执行完毕退出的意思。Bar函数的分析类似,其字节码文件对应的指令如下

    getstatic #13<Test.count>
    iconst_1
    iadd
    dup
    putstatic #13<Test.count>
    sipush 1000
    if_icmplt 29(+17)
    iconst_0
    putstatic #13<Test.count>
    new #25
    dup
    ldc #27<count overflow>
    invokespecial #29<java/lang/Exception.<init>>
    athrow
    getstatic #13<Test.count>
    ireturn
    
  • 相关阅读:
    20200209 ZooKeeper 3. Zookeeper内部原理
    20200209 ZooKeeper 2. Zookeeper本地模式安装
    20200209 Zookeeper 1. Zookeeper入门
    20200206 尚硅谷Docker【归档】
    20200206 Docker 8. 本地镜像发布到阿里云
    20200206 Docker 7. Docker常用安装
    20200206 Docker 6. DockerFile解析
    20200206 Docker 5. Docker容器数据卷
    20200206 Docker 4. Docker 镜像
    Combining STDP and Reward-Modulated STDP in Deep Convolutional Spiking Neural Networks for Digit Recognition
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3178064.html
Copyright © 2011-2022 走看看