引用
Java语言中包含3种引用:
1.符号引用
String str=new String();
str即为符号引用,当类装载器对class文件进行装载时,在解析阶段对符号引用进行转换,转换为直接引用,讲解类装载器时会详细介绍这个阶段。
2.直接引用
直接引用实际上就是指向了对象句柄表中的对应项,对象句柄表中存储了对象在内存中的物理地址以及直接引用之间的映射。
3.物理地址
物理地址存储在对象句柄表中,物理地址由:段地址*16+偏移地址组成,物理地址就是这个对象在内存中的绝对路径。
对象句柄表
方法
Java语言中分为两种方法:
- 1. Java方法
由Java语言编写的方法,比如我们自己编写的hello world程序。
- 2. 本地方法
真正的Java底层的实现,由其他语言编写,比如由C语言编写的保存在dll文件中的函数。实际上Java API中的操作都是由这些底层函数实现的。
方法与指令之间的关系
我们写的Java方法最后都会被转换成Java虚拟机的指令,由Java虚拟机装载这些指令之后,由其他类调用。
指令
Java虚拟机的指令是由我们写的Java方法解析而成,可以说Java虚拟机的指令就是我们写的Java方法的底层实现。
例如:
iconst_2
这条指令就是将int类型的2放到栈顶中。
一. 操作码和操作数:
操作码就是这条指令执行的操作,例如入栈、出栈等。
操作数就是这条指令操作的数值,例如0、1、2、3等。
上面的指令的操作码就是:iconst,操作数就是0
命名空间
被类装载器的类都放在自己的命名空间中,这个命名空间中存储了这个类所调用的所有的类。
我们讲解到类装载器时会详细介绍类装载器装载类的步骤。
Java虚拟机实例
我们运行的每一个Java程序在Java虚拟机中都会创建出这个Java程序对应的Java虚拟机实例,我们运行2个Java程序就会产生2个Java虚拟机实例。
注意:当这个Java程序运行完毕之后,这个Java虚拟机实例将自动销毁。
注意:Java虚拟机实例可以说在Java虚拟机中代表了这个Java程序。
可以强制销毁这个Java虚拟机实例
System.exit(0);
方法与线程之间的关系
在Java程序中写的所有方法都可以看成是线程。
例如:
import java.util.Date; public class Test { public static void main(String[] args) { try { System.out.println(new Date()); Thread.sleep(10000); System.out.println(new Date()); } catch (InterruptedException e) { e.printStackTrace(); } } }
输出:
Fri Sep 28 10:14:40 CST 2012
Fri Sep 28 10:14:50 CST 2012
可以看到,调用线程休眠方法对普通方法同样有效,可以证明在Java虚拟机中方法就是线程这一观点。
线程
在Java虚拟机中线程分两种:
- 1. 守护线程
守护线程指的是Java虚拟机内部的线程,比如说GC(垃圾收集器)就是个守护线程。
- 2. 非守护线程
Java程序中的所有方法都可以看成是非守护线程。
注意:如果方法和线程的概念比较模糊,请参考方法与线程之间的关系、Java虚拟机实例。
pc寄存器
Java虚拟机同时可以执行多个线程,每一个线程都拥有自己的pc寄存器,每一个线程都可以调用方法,如果这个线程调用的方法是Java方法,我们知道Java方法最后的本质就是一堆Java虚拟机指令,pc寄存器就会指向了这些指令的地址。如果调用的方法的本地方法,是由其他语言实现的方法,那么pc寄存器就什么都不存储。
注意:pc寄存器实际上就是存储了这个线程当前调用的Java方法的地址
returnAddress类型
我们写的Java方法最后都会被解析成一条条指令,这些指令都会存储在内存中。
我们调用某一个方法的时候必须要知道这些方法解析成的指令的地址, returnAddress类型会一个一个存储每一条指令的地址。当我们执行到最后一条指令,returnAddress类型只会存储到最后一条指令的地址
boolean类型
boolean类型在Java虚拟机指令中,实际上都是int类型。
0:true
1:false