一、JVM与java体系结构
1 虚拟机的结构
2 java的编译
??有句话说java是半编译半解释型语言,因为从*.java到*.class文件的过程是编译。而*.class文件的运行是解释。
??但其实*.class文件的运行过程是半编译半解释的。有些需要反复用到的字节码是直接编译成机器指令来执行的。就好比域名的解析,常用访问的域名解析是直接通过本地域名服务器,不常用的才会自顶向下层层解析。例如for循环中的代码是要重复利用的,就把这段字节码编译成机器指令缓存起来,每次循环都调用缓存区中的机器指令,而不需要进行解释。如图:
3 jvm的指令集
??指令集架构有基于栈的指令集架构和基于寄存器的指令集架构。
??jvm中使用的就是基于栈的指令集架构。它的好处是不需要硬件支持,可移植性高,零地址指令多。但性能不及寄存器式架构(如x86汇编)
??栈式架构必然是大量使用到栈。例如我们将如下代码进行反汇编:
package com.spd.jvm;
public class Test {
public static void main(String[] args) {
int i = 2;
int j = 3;
int k = 2 + 3;
}
}
??得到的结果是:
iconst_2 // 将int型数2压栈
istore_1 // 将栈顶int型存入本地变量1
iconst_3 // 将int型数3压栈
istore_2 // 将栈顶int型存入本地变量2
iconst_5 // 将int型数5压栈
istore_3 // 将栈顶int型存入本地变量3
return // 从当前方法返回void
??而对x86汇编而言是这么写的:
mov ds : [0], 2 ; 设ds : [0]为i
mov ds : [4], 3 ; 设ds : [4]为j
mov eax, ds : [0]
add eax, ds : [4]
mov ds : [12], ax ; 设ds : [12]为k,k = ax = i + j
ret
??由此可见,确实比起x86汇编更多使用到了栈。另外也能看出来同一功能栈式架构比寄存器式架构需要用更多指令,但是他的指令集更小。
二、类加载子系统
1 类加载子系统的结构
2 类加载子系统的作用
??类加载子系统只负责类的加载,而类能否运行由执行引擎决定。
3 类加载的加载过程
??① 通过一个类的全限定名获取定义此类的二进制字节流
??② 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
??③ 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口
4 类加载的验证过程
??① 验证:验证魔数及版本号。
??② 准备:为类变量分配内存并设置为他们的初始值。初始化阶段才赋值。(不会分配final修饰的static,因为他们在编译过程就已经分配了。准备阶段只会进行显式初始化。也不会为实例变量分配初始化。)
package com.spd.jvm;
public class Test {
private static int age = 18;
private static char sex = '男';
public static String name = "spd";
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
??③ 解析:将常量池中的符号引用转换成直接引用。
5 类加载的初始化过程
|