JVM的Class加载机制1(里面有string和stringbuffer在.class层面的区别)

在这里插入图片描述1.Class Files:将.java文件编译为.class文件
2.Class Loader Subsystem:将.class文件加载到jvm虚拟机中去。
3.Runtime Data Areas:运行时内存区域的划分。
4.Execition Engine:执行引擎,包括两部分。GC:垃圾回收器。JIT:java的编译。
5.Native Method Interface:与硬件进行交互的接口。

1)Class File:
Class字节码文件是jvm认识的一种文件,里面的地址都是逻辑地址。最后需要运行在操作系统中,操作系统只能识别真实的物理地址。此时需要动态链接,就是在运行时动态地绑定对象,对象地址。
Class字节码文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件中,中间没有添加任何的分隔符,这使得整个Class文件中存储的内容几乎全部是程序运行的必须数据。
Class字节码文件只有两种数据类型:无符号数(u)和表(info)

下面我们看一下.class文件。
下面的代码为string和stringbuffer的区别以及try和finally哪个更加优先。

public class Test {

    public static void m1() {
        String str = "";
        for (int i = 0; i < 10; i++) {
            str = str + "xxo.";
        }
        System.out.println(str);
    }

    public static void m2() {
        StringBuffer str = new StringBuffer();
        for (int i = 0; i < 10; i++) {
            str.append("xxo,");
        }
        System.out.println(str);
    }

    public static String m3() {
        String str = "hello";
        try {
            return str;
        } finally {
            str = "nx";
        }
    }

    public static void main(String[] args){
        System.out.println(m3());
    }

}

运行以后在out中找到对应的class文件,右键打开控制台在这里插入图片描述打开控制台之后输入javap -verbose Test.class
javap:字节码的注记指令。
verbose:输出附加信息。
Constant pool:常量池。
在这里插入图片描述
方法m1的注记符提示
第8条指令为if-icmpge if(如果) i cmp(比较)ge(>=)这条指令为条件判断语句
第34条指令为goto(跳转)
第八条到第34条指令之间为for语句块的内容
String的创建在第11条指令的new调用了class java/lang/StringBuilder 第15行invokespecial调用了Method java/lang/StringBuilder.""😦)V
在这里插入图片描述
而我们同样的来看方法m2,在里面没有new也没有invokespecial,而是第19行指令使用了invokevirtual 并且调用了Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
由此可见String和StringBuffer在class层面的区别。
在这里插入图片描述接下来我们研究一下try和finally的优先级。
如下图所示,String str = “hello”; 在class中的操作如下(第0条指令ldc #14 是将“hello”放入常量池14号位置中,第二条指令astore_0将查找的常量存储到0号变量上第三条指令aload_0将0号变量的值进行压栈,第四条指令astore_1再将常量存储到1号变量上。)第8条指令将hello压栈,第10条指令areturn将hello返回。所以返回的值为hello不是nx。try比finally优先级高。

在这里插入图片描述如果想要具体了解各个指令的含义可以上这个网站查看
https://docs.oracle.com/javase/specs/index.html
在这里插入图片描述在这里插入图片描述这个是java的虚拟机规范

接着打开第四章内容
在这里插入图片描述它的左侧栏有各种注记符的具体内容,点击即可。
在这里插入图片描述下图为class文件的结构。我会通过二进制流来展示一下class文件。
在这里插入图片描述以下面的代码产生的class文件举例。

public class IntTest {
    public static void main(String[] args){
        int a = 1;
        int b = 200;
        int c = a+b;
        System.out.println(c);
    }
}

打开控制台之后输入javap -verbose IntTest.class
在这里插入图片描述

右键在文件夹中打开class文件,使用notepad++打开后如图(你九成九看不懂)
在这里插入图片描述这里需要你点开上面栏中的插件,安装Hex-editor(用16位显示),使用插件后打开如下。我将给出一部分的解读。
在这里插入图片描述
对照这个官方文档来看
在这里插入图片描述首先是u4,4个字节的无符号位数表示的magic(魔法数,是校验位检验这个文档是否为class文档)这里是ca fe ba be
u2 minor_version;00 00
u2 major_version;00 34(注意是16位的,换算成十进制为52)
这两个代表的是class文件的副版本和主版本。
控制台中看到
在这里插入图片描述u2 constant_pool_count;00 24 (十进制为00 36)是常量池的个数。
cp_info constant_pool[constant_pool_count-1];00 24(十进制为00 36)常量池个数减一。在这里插入图片描述
从1开始到35共35个。
具体解析cp_info,ctrl+f搜索官方文档
在这里插入图片描述这里规定了cp_info的格式。u1_tag; 和 u1_info[];是个复合格式。共35个这种复合格式。根据不同tag值,info也不同
在这里插入图片描述
u1_tag 0a(10)为CONSTANT_Methodref,继续ctrl+f页面内查找CONSTANT_Methodref
在这里插入图片描述可见u1_info格式为
CONSTANT_Methodref_info {
u1 tag;
u2 class_index;
u2 name_and_type_index;
}
这里需要读u2 class_index;00 05(5)以及 u2 name_and_type_index; 00 17(23),在控制台中看到对应。
在这里插入图片描述
在这里插入图片描述在这里插入图片描述接下来的8位码解析操作基本雷同就不再赘述。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值